Я новичок в C ++ и просто пытаюсь написать некоторый код, чтобы сам поэкспериментировать.
Недавно я столкнулся с проблемой, которую не могу отладить.
char acExpReason[128];
char acReason[] = "An error message is information displayed when an unexpected condition occurs, usually on a computer or other device. On modern operating systems.";
memcpy(acExpReason, acReason, sizeof(acExpReason));
std::string strExpReason(acExpReason);
Я использую VS2005 для добавления точек останова к каждой строке для отладки.
когда он достигает точки останова во второй строке, имя переменной и информация о значении в Autos:
acReason 0x00f6f78c «ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ» char [147]
acExpReason 0x00f6f828 «ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̺» char [128]
когда он достигает точки останова в третьей строке, информация об имени и значении переменной в Autos:
acExpReason 0x00f6f828 «ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̺» char [128]
acReason 0x00f6f78c «Сообщение об ошибке — это информация, отображаемая при возникновении непредвиденного состояния, обычно на компьютере или другом устройстве. В современных операционных системах.» символ [147]
когда он достигает точки останова в четвертой строке, информация об имени и значении переменной в Autos:
acExpReason 0x00f6f828 «Сообщение об ошибке — это информация, отображаемая при возникновении непредвиденного состояния, обычно на компьютере или другом устройстве. На современном charº» char [128]
acReason 0x00f6f78c «Сообщение об ошибке — это информация, отображаемая при возникновении непредвиденного состояния, обычно на компьютере или другом устройстве. В современных операционных системах.» символ [147]
strExpReason Bad Ptr
после выполнения последней строки информация в Autos:
acExpReason 0x00f6f828 «Сообщение об ошибке — это информация, отображаемая при возникновении непредвиденного состояния, обычно на компьютере или другом устройстве. На современном charº» char [128]
acReason 0x00f6f78c «Сообщение об ошибке — это информация, отображаемая при возникновении непредвиденного состояния, обычно на компьютере или другом устройстве. В современных операционных системах.» символ [147]
strExpReason «Сообщение об ошибке — это информация, отображаемая при возникновении непредвиденного состояния, обычно на компьютере или другом устройстве. На современном компьютере»
в основном, мой код хочет просто иметь полную строку сообщения, которая хранится в acReason [], а также есть копия полного сообщения в фиксированной длине (здесь 128).
но я не знаю, почему acExpReason и strExpReason (строковая версия acExpReason) заканчиваются странными символами «ÌÌÌÌÌÌÌ̺», которые мне не нужны (так как я буду использовать эту строку для сравнения с другой строкой позже).
Я попытался использовать memcpy, strcpy и strncpy, и все они в итоге получили этот набор странных символов в конце строки.
Кто-нибудь может помочь?
Спасибо заранее.
В C все строковые функции, такие как strcpy, а также конструктор для c ++ std::string
принимать char*
в качестве параметра, кроме char*
должен заканчиваться байтом, содержащим `\ 0`.
У acExpReason нет нуля, заканчивающего его, поэтому все строковые функции ищут следующий 0 байт в памяти. У acReason есть завершающий `\ 0`. Обычный strcpy будет работать, поскольку он также копирует 0, однако @VladLazarenko говорит, что размер буфера слишком мал, что приведет к перезаписи всей памяти.
Для работы memcpy вам нужно скопировать на один байт меньше буфера и сделать последний байт буфера 0.
например
memcpy(acExpReason, acReason, sizeof(acExpReason)-1);
acReason[sizeof(acExpReason)-1] = 0;
std::string strExpReason(acExpReason);
Этот конструктор требует строки в стиле C. тем не мение acExpReason
не является строкой в стиле C, так как не имеет завершающего нулевого байта. (Как конструктор узнает, сколько байтов должно быть в строке?) Вы должны следовать правилам.
Вы также можете использовать string
конструктор, который принимает диапазон итератора —
std::string strExpReason(acExpReason, acExpReason+sizeof(acExpReason));