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
Is passing the buffer as &buffer[0] better programming style than passing buffer? (I prefer &buffer[0].)
&buffer[0]
makes the code less readable to me. I have to pause for a second and wonder why someone used it instead of just passing buffer
. Sometimes you have to use &buffer[0]
(if buffer
is a std::vector
), but otherwise, stick with the standard C style.
Is there a maximum size that is considered safe for stack allocated buffers?
I doubt there's any practical limit, as long as you're using the stack reasonably. I've never had any problems in my development.
If I'm reading MSDN correctly, threads on Windows default to 1MB of stack size. This is configurable. Other platforms have other limits.
Is static char buffer[N]; faster? Are there any other arguments for or against it?
On the one hand, it might reduce the need to commit memory pages for stack, so your app might run faster. On the other hand, going to the BSS segment or equivalent might reduce cache locality compared to the stack, so your app might run slower. I seriously doubt you'd notice the difference either way.
Using static
is not threadsafe, while using the stack is. That's a huge advantage to the stack. (Even if you don't think you'll be multithreaded, why make life harder if that changes in the future?)
When using static buffers you can have your function return have the const char * return type. Is this a good idea? (I do realize that the caller will need to make his own copy to avoid that the next call would change the previous return value.)
Const correctness is always a good thing.
Returning pointers to static buffers is error-prone; a later call might modify it, another thread might modify it, etc. Use std::string
instead or other auto-allocated memory instead (even if your function needs to deal internally with char buffers such as your GetCurrentDirectory
example.)
What about using static char * buffer = new char[N]; and never deleting the buffer? (Reusing the same buffer each call.)
Less efficient than just using static char buffer[N]
, since you need a heap allocation.
I understand that heap allocation should be used when (1) dealing with large buffers or (2) maximum buffer size is unknown at compile time. Are there any other factors that play in the stack/heap allocation decision?
See Justin Ardini's answer.
Should you prefer the sprintf_s, memcpy_s, ... variants? (Visual Studio has been trying to convince me of this for a long time, but I want a second opinion :p )
This is a matter of some debate. Personally, I think these functions are a good idea, and if you're targeting Windows exclusively, then there's some benefit to taking the preferred Windows approach and using those functions. (And they're fairly straightforward to reimplement if you later need to target something other than Windows, as long as you don't rely on their error-handling behavior.) Others think that the Secure CRT functions are no more secure than properly used C and introduce other disadvantages; Wikipedia links to a few arguments against them.