Моя цель — сгенерировать новый массив с правильным количеством точек и скопировать в него старый массив символов.
При использовании strcpy_s выбрасывается исключение. Я не могу понять, почему возникает исключение, в котором говорится, что буфер слишком мал. Я не могу использовать векторы или строки. Как я могу исправить это, используя массивы strcpy_s и char?
char str[4] = { 't', 'e', 's', 't' };
int allocated = 4;
char * reservedString = new char[allocated]();
strcpy_s(reservedString, allocated, str);
Обновлено: Изменение моего кода для добавления одного в массив дает мне то же исключение «слишком маленький буфер».
char str[4] = { 't', 'e', 's', 't' };
int allocated = 4;
char * reservedString = new char[allocated+1]();
strcpy_s(reservedString, allocated, str);
Обновлено еще раз: Как кто-то прокомментировал, str необходимо установить на размер 5 и включить нулевой терминатор. Спасибо, это исправило мою проблему.
Обновленный код:
char str[5] = { 't', 'e', 's', 't', '\0'};
int allocated = 5;
char * reservedString = new char[allocated]();
strcpy_s(reservedString, allocated, str);
Вы не выделяете нужную память:
char str[4] = { 't', 'e', 's', 't' };
Он выделяет 5 байтов, по 4 на каждый символ плюс завершающий нуль.---
Делать:
char str[4] = { 't', 'e', 's', 't' };
char * reservedString = new char[5]();
strcpy_s(reservedString, allocated, str);
Или:
char str[4] = { 't', 'e', 's', 't' };
char * reservedString = new char[5]();
strcpy(reservedString, str);
Я попытался добавить один в массив, и он все равно дал мне исключение «слишком маленький буфер». Я беспокоюсь об использовании strcpy, потому что он будет записывать слишком много памяти, если у меня есть ошибка в моем коде.
Спасибо, @TonyK, это была моя проблема!
char str[4] = { 't', 'e', 's', 't' };
— это 4-байтовый массив в памяти. Это не строка, и совершенно случайно, когда после этих 4 байтов будет стоять «завершающий» ноль, а между ними произвольное количество других данных.
Тем не менее, strcpy_s()
ожидает копирования строки с нулевым завершением, только одно из дополнений, которое он делает, — это проверка того, будет ли исходная строка соответствовать месту назначения. Не будет, вот почему вы получаете ошибку.
[...] the following errors are detected at runtime and call the currently installed constraint handler function:
* src or dest is a null pointer
* destsz is zero or greater than RSIZE_MAX
* destsz is less or equal strnlen_s(src, destsz); in other words, truncation would occur
* overlap would occur between the source and the destination strings
Вы получаете третий, произойдет усечение «мусорных» байтов.
Вам нужно пять символов, чтобы сохранить строку с нулевым завершением "test"
. Ваш массив str
состоит всего из четырех символов без нулевого терминатора. Если вам нужен нулевой терминатор, объявите его следующим образом:
char str[] = "test";
Тогда нужно конечно
int allocated = 5;
И после этого:
char * reservedString = new char[allocated];
strcpy_s(reservedString, allocated, str);
@tevemadar (camelbird?): Спасибо, что указали на это. Я отредактировал свой ответ соответственно.
Да, это венгерский. Тевемадар - персонаж из более старого мультсериала en.m.wikipedia.org/wiki/Jamie_and_the_Magic_Torch (в оригинале назывался "Птица Ю-ху").
str
это не строка. Строка — это последовательность символов, отличных от NUL, оканчивающаяся символом NUL.
Вы должны передать размер буфера в strcpy_s()
, а не максимальный размер строки (который на единицу меньше).
То есть, если вы должны использовать strcpy_s()
вообще. Вы не должны.
Используйте strcpy()
или, если у вас уже есть точный размер, memcpy()
или std::copy_n()
.
В качестве примечания, обнуление памяти только для того, чтобы развернуться и перезаписать ее, — бессмысленная трата.
Он не выделяет пять байтов! Это часть проблемы:
str
не завершается нулем.