С++ strcpy_s выдает ошибку при копировании в новый массив символов

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

При использовании 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);
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
492
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

Он не выделяет пять байтов! Это часть проблемы: str не завершается нулем.

TonyK 06.04.2019 23:06

Я попытался добавить один в массив, и он все равно дал мне исключение «слишком маленький буфер». Я беспокоюсь об использовании strcpy, потому что он будет записывать слишком много памяти, если у меня есть ошибка в моем коде.

EmptyStuff 06.04.2019 23:06

Спасибо, @TonyK, это была моя проблема!

EmptyStuff 06.04.2019 23:10

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?): Спасибо, что указали на это. Я отредактировал свой ответ соответственно.

TonyK 07.04.2019 00:01

Да, это венгерский. Тевемадар - персонаж из более старого мультсериала en.m.wikipedia.org/wiki/Jamie_and_the_Magic_Torch (в оригинале назывался "Птица Ю-ху").

tevemadar 07.04.2019 00:10
  1. strэто не строка. Строка — это последовательность символов, отличных от NUL, оканчивающаяся символом NUL.

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

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

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

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

Другие вопросы по теме