Я пытаюсь запустить свой c++ код, введение которого в этот новый код привело к повреждению памяти, может ли кто-нибудь помочь мне в этом, что бы это вызвало. После вызова delete я столкнулся с этой проблемой. Я также попытался разместить newArgs[SZ] = '\0';
после каждого вызова strncpy
.
Ошибка говорит:
КОПИРОВАНИЕ HEAP ОБНАРУЖЕНА после нормального блока (# 274) в 0X00C09600 и т.д.
int main(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* argc, int nShowCmd){
MyClass *obj;
char args[] = " hello world";
int SZ = strlen(args);
int argsLength = 0;
if(argc != NULL)
argsLength=strlen(argc);
SZ+=argsLength;
char *newArgs = new char[SZ];
strncpy(newArgs, "",SZ);
if(argc != NULL)
strncpy(newArgs, argc,argsLength);
StrCat(newArgs,args);
obj = new MyClass(newArgs);
delete[] newArgs;
return 0;
}
Вы извлекаете длину строки argc. Это без конечного нулевого байта:
argsLength=strlen(argc);
Позже вы копируете argc в свой буфер. Но вы копируете только символы argsLength, которые являются строкой без конечного нулевого байта. strncpy будет только копировать содержимое строки, а не добавлять конечный нулевой байт (см. man strncpy).
strncpy(newArgs, argc,argsLength);
Сразу же после strncpy вы добавляете другую строку в newArgs.
StrCat(newArgs,args);
В зависимости от содержимого newArgs после выделения (который может быть случайным, при отладке он, вероятно, будет заполнен специальным шаблоном) strcat fill не находит конечный нулевой байт в newArgs и, таким образом, будет читаться за пределами выделенного буфера (пока он не будет находит нулевой байт) и добавит ваши строковые аргументы там - где-то в куче и вне выделенной памяти. Это куча коррупции.
Кроме:
Я бы переписал вашу программу таким образом (не компилировал и не тестировал ее):
int main(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* argc, int nShowCmd)
{
const char args[] = " hello world";
std::string newArgs;
if(argc != NULL)
newArgs = argc;
newArgs += args;
// Use the line that you prefer
MyClass obj1(newArgs.c_str());
std::unique_ptr<MyClass> obj2(new MyClass(newArgs.c_str()));
return 0;
}
Я не могу видеть вашу реализацию MyClass
но я готов поспорить, что она хранит копию указателя, переданного в конструктор, и что она также пытается работать с этим после вашего вызова на delete
.
Я настоятельно рекомендую вам остановить new
char*
в C++ и использовать strings
.
SIZE
? Он используется, но никогда не объявляется.argsLength
вSIZE
не вSZ
, поэтомуnewArgs
не будет достаточно большим.