If I request a char str[12], that reserves 12 characters?
Yes, this reserves 12 characters (bytes) on the stack.
I presume that memory has then been assigned?
str
now points to the beginning of 12 bytes of contiguous memory that has been allocated on the stack.
So how does null termination work? Is that at the end of the 12 characters (with spaces padding?), or if the number only uses 2 characters, would it happen after two?
In this case you have to null-terminate the string yourself (it doesn't automatically happen with this type of declaration).
So if you wanted to make str
hold some (null-terminated) string value, you would do the following:
str[0] = 'c';
str[1] = 'a';
str[2] = 't';
str[3] = '\0';
Another way to get a null-terminated string is to do the following:
char *str = "cat"; // this is null-terminated
There is no automatic padding with spaces.
And if I use the pointer later in a simple struct, will the memory be cleared automatically or do I need a destructor?
If the pointer is pointing to a piece of memory allocated on the stack, then the memory will be recovered when the stack is popped. Otherwise, if you allocate memory on the heap such as:
char *newStr = new char[12];
char *mallocStr = (char*) malloc(sizeof(char) * 12);
Then you will have to de-allocate the memory using delete
or free
(depending on which method you used).
Does the destructor need to know the initialize buffer size?
In this context we're talking about heap-allocated memory and therefore the answer is no. The system knows how much memory was allocated. That's why you just give the pointer to delete
and free
without having to provide a size.
Why does no one bother to calculate the buffer length from the actual number?
You can if you know that your number will never exceed a certain amount (say, 4 digits), but it's usually easier to just give the maximum possible length, because in the end you'll only be wasting a few bytes per string, which isn't a big deal unless you have some really tight memory constraints.
Is snprintf recommended over itoa?
I would say yes because snprintf
is considered "safe" because it respects the buffer size that you give it, whereas itoa
will happily fill your buffer without checking its size (possibly running past the allocated space and overwriting other memory).
int num = 12345;
char *str = new char[4];
// this is bad because str is not big enough to hold the number
// itoa does not check buffer size and will overrun the buffer (overwriting other data)
str = itoa(num, str);
// snprintf takes the buffer size as one of it's arguments
// in this case the whole number will not fit, but at least we don't overrun the buffer
snprintf(str, 4, "%i", num);
Both snprintf
and itoa
will null-terminate the strings for you.