c ++ new/delete和char*

a3d*_*fcv 17 c++ char new-operator

任何人都可以帮助我,为什么我在尝试释放分配的内存时收到错误消息:检测到堆损坏.CTR检测到应用程序在堆缓冲区结束后写入内存.

char *ff (char *s){
    char *s1 = new char [strlen(s)];
    strcpy(s1, s);
    return s1;
}

int _tmain(int argc, _TCHAR* argv[])
{
    char *s = new char [5];

    strcpy(s, "hello");
    char *s2 = ff(s);

    delete []s;     // This works normal
    delete []s2;    // But I get an error on that line
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Alo*_*ave 44

char *s = new char [5];
strcpy(s, "hello");
Run Code Online (Sandbox Code Playgroud)

导致未定义的行为(UB).
你的写作超出了分配的memery的范围.您为5字符分配了足够的内存,但您的字符串包含6字符,包括\0.

一旦你的程序导致了这个UB,所有的赌注都会关闭,任何行为都是可能的.

你需要:

char *s = new char [strlen("hello") + 1];
Run Code Online (Sandbox Code Playgroud)

事实上,理想的解决方案是使用std::string而不是char *.这些都是精确std::string避免的错误.并且没有真正需要使用char *而不是std::string在您的示例中.
std::string:

  • 你不需要new任何东西
  • 你不需要delete任何东西&
  • 你可以做的一切std::string,你有做char *.


Joh*_*hnB 13

new char [strlen(s)];不计算结束\0字符,因此缓冲区太短一个字符.


eca*_*mur 9

strcpy包括空终止符; strlen才不是.写:

char *s1 = new char [strlen(s) + 1];
Run Code Online (Sandbox Code Playgroud)


iab*_*der 6

来自man strcpy(3):

strcpy()函数将src指向的字符串(包括终止空字节('\ 0'))复制 到dest指向的缓冲区.

所以,你需要保留6字节5的字符串,并1NULL字节

char *s = new char [6];
strcpy(s, "hello");
Run Code Online (Sandbox Code Playgroud)