Если я запрашиваю строку символов [12], которая резервирует 12 символов?
Да, это резервирует 12 символов (байтов) в стеке .
Я предполагаю, что память была назначена?
str
теперь указывает на начало 12 байтов непрерывной памяти, которая была выделена в стеке.
Так как же работает нулевое завершение?Это в конце 12 символов (с пробелами?), Или если число использует только 2 символа, это произойдет после двух?
В этом случае вы должны завершить нулемСтрока самостоятельно (это не происходит автоматически при объявлении этого типа).
Поэтому, если вы хотите, чтобы str
содержал какое-либо (заканчивающееся нулем) строковое значение, вы бы сделали следующее:
str[0] = 'c';
str[1] = 'a';
str[2] = 't';
str[3] = '\0';
Другой способ получить строку с нулевым символом в конце - это сделать следующее:
char *str = "cat"; // this is null-terminated
Нет автоматического заполнения пробелами.
И если яиспользовать указатель позже в простой структуре, очистится ли память автоматически или мне нужен деструктор?
Если указатель указывает на часть памяти, выделенную в стеке, то память будетбыть восстановленным, когда стек вытолкнут.В противном случае, если вы выделите память в куче, например:
char *newStr = new char[12];
char *mallocStr = (char*) malloc(sizeof(char) * 12);
Тогда вам придется отменить выделение памяти с помощью delete
или free
(в зависимости от того, какой метод вы использовали).
Нужно ли деструктору знать размер инициализируемого буфера?
В этом контексте мы говорим о выделенной памяти кучи, и поэтому ответ - нет.Система знает, сколько памяти было выделено.Вот почему вы просто указываете на delete
и free
без указания размера.
Почему никто не удосужился вычислить длину буфера из фактического числа?
Вы можете, если знаете, что ваш номер никогда не превысит определенной суммы (скажем, 4 цифры), но обычно проще просто указать максимально возможную длину, потому что в итоге вы будете тратить только несколькобайт на строку, что не имеет большого значения, если у вас нет действительно жестких ограничений памяти.
Рекомендуется ли snprintf поверх itoa?
Я бы сказал да, потому что snprintf
считается «безопасным», потому что он учитывает размер буфера, который вы ему даете, тогда как itoa
успешно заполнит ваш буфер, не проверяя его размер (возможно, пробегая выделенное пространство и перезаписывая другую память).
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);
И snprintf
, и itoa
завершат строки для вас нулем.