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].)
It depends on the coding standards. I personally prefer: buffer + index
instead of &buffer[index]
but it's a matter of taste.
Is there a maximum size that is considered safe for stack allocated buffers?
It depends on the stack size. If the amount of stack needed for your buffer exceeds the amount available on the stack, it result a stack-overflow.
Is static char buffer[N]; faster? Are there any other arguments for or against it?
Yes, it should be faster. See also this question: Is it bad practice to declare an array mid-function
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.)
Not sure what static means in this case but:
If variable is declared on stack( char buf[100]
):
You should not return references to stuff that is declared on the stack. They will be trashed at next function call/declaration (e.g. when the stack is used again).
If the variable is declared as static static
it will make your code non-reentrant. strtok is an example in this case.
What about using static char * buffer = new char[N]; and never deleting the buffer? (Reusing the same buffer each call.)
It is a possibility, though not recommended because it makes your code non-reentrant.
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?
Stack size of the running thread is too small to fit stack declaration (previously mentioned).
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 )
If you want your code to be portable: No. But the effort in creating a portable macro is quite small in this case:
// this is not tested - it is just an example
#ifdef _WINDOWS
#define SPRINTF sprintf_s
#else
#define SPRINTF sprintf
#endif