C ++ strcpy_s выдает ошибку при копировании в новый массив символов - PullRequest
0 голосов
/ 06 апреля 2019

Моя цель - создать новый массив с правильным количеством точек и скопировать в него старый массив символов.

При использовании 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);

РЕДАКТИРОВАТЬ 2: Как кто-то прокомментировал, str должен быть установлен в 5 и иметь нулевой терминатор.Спасибо, это исправило мою проблему.

Обновленный код:

    char str[5] = { 't', 'e', 's', 't', '\0'};
    int allocated = 5;
    char * reservedString = new char[allocated]();
    strcpy_s(reservedString, allocated, str);

Ответы [ 4 ]

1 голос
/ 07 апреля 2019
  1. str не является строкой .Строка - это последовательность не-NUL символов, оканчивающаяся на NUL.

  2. Вы должны передать размер буфера в strcpy_s(), а не в максимальную строку-размер (который на один меньше).

  3. То есть, если вы должны использовать strcpy_s() на всех . Вы не должны.

    Используйте strcpy(), или, как у вас уже есть точный размер, memcpy() или std::copy_n().

  4. Как примечание: обнуление памяти только для того, чтобы перевернуть и перезаписать ее, является бессмысленной тратой.

1 голос
/ 07 апреля 2019

char str[4] = { 't', 'e', 's', 't' }; - это 4-байтовый массив в памяти. Это не строка, и совершенно случайно, когда после этих 4 байтов возникает «завершающий» ноль, а между ними - произвольное количество других данных.
Тем не менее, strcpy_s() ожидает копирования строки с нулевым символом в конце, только одно из дополнительных действий - проверка соответствия исходной строки цели. Не будет, поэтому вы получаете ошибку.

[...] следующие ошибки обнаруживаются во время выполнения и вызывают установленную в настоящее время функцию обработчика ограничения:
* src или dest - нулевой указатель
* destsz равен нулю или больше, чем RSIZE_MAX
* destsz меньше или равно strnlen_s (src, destsz); другими словами, усечение произойдет
* будет происходить перекрытие между исходной и целевой строками

Вы получите третий, произойдет усечение байтов «мусора».

1 голос
/ 07 апреля 2019

Вам нужно пять символов для хранения строки с нулем в конце "test".Ваш массив str состоит из четырех символов, без нулевого терминатора.Если вы хотите использовать нулевой терминатор, объявите его так:

char str[] = "test";

Затем вам нужно, конечно,

int allocated = 5;

И после этого:

char * reservedString = new char[allocated];
strcpy_s(reservedString, allocated, str);
0 голосов
/ 07 апреля 2019

Вы не выделяете нужную память:

char str[4] = { 't', 'e', 's', 't' };

Он выделяет 5 байтов, 4 для каждого символа плюс нулевой терминатор .---

Do:

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);
...