Dealing with char buffers

前端 未结 9 1718
情书的邮戳
情书的邮戳 2021-02-08 02:33

As a C++ programmer I sometimes need deal with memory buffers using techniques from C. For example:

char buffer[512];
sprintf(buffer, \"Hello %s!\", userName.c_s         


        
9条回答
  •  迷失自我
    2021-02-08 02:57

    • Buffer or &Buffer[0] is exactly the same. You could even write Buffer+0. Personally I prefer just to write Buffer (and I think most developers also prefer this), but this is your personal choice
    • The maximum depends on how big and how deep your stack is. If you are already 100 functions deep in the stack, the maximum size will be smaller. If you can use C++, you could write a buffer class that dynamically chooses whether to use the stack (for small sizes) or the heap (for large sizes). You will find the code below.
    • A static buffer is faster since the compiler will reserve the space for you beforehand. A stack buffer is also fast. For a stack buffer the application just has to increase the stack pointer. For a heap buffer, the memory manager has to find free space, ask the operating system for new memory, afterwards free it again, do some bookkeeping, ...
    • If possible use C++ strings to avoid memory leaks. Otherwise, the caller has to know whether he has to free the memory afterwards or not. The downside is that C++ strings are slower than static buffers (since they are allocated on the heap).
    • I wouldn't use memory allocation on global variables. When are you going to delete it? And can you be sure that no other global variable will need the allocated memory (and be used before your static buffer is allocated)?
    • Whatever kind of buffer you use, try to hide the implementation from the caller of your function. You could try to hide the buffer-pointer in a class let the class remember whether the buffer is dynamically allocated or not (and thus should delete it in its destructor or not). Afterwards it's easy to change the type of the buffer, which you can't do if you just return a char-pointer.
    • Personally I prefer the normal sprintf variants, but that's probably because I still have lots of older code and I don't want a mixed situation. In any case, consider using snprintf, where you can pass the buffer size.

    Code for dynamic stack/heap buffer:

    template
    class DynamicBuffer
       {
       private:
          const static size_t MAXSIZE=1000;
       public:
          DynamicBuffer() : m_pointer(0) {if (BUFSIZE>=MAXSIZE) m_pointer = new eltType[BUFSIZE];}
          ~DynamicBuffer() {if (BUFSIZE>=MAXSIZE) delete[] m_pointer;};
          operator eltType * () { return BUFSIZE>=MAXSIZE ? m_pointer : m_buffer; }
          operator const eltType * () const { return BUFSIZE>=MAXSIZE ? m_pointer : m_buffer; }
       private:
          eltType m_buffer[BUFSIZE

提交回复
热议问题