c ++ new / delete和char *

时间:2012-11-06 08:27:12

标签: 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;
}

8 个答案:

答案 0 :(得分:44)

char *s = new char [5];
strcpy(s, "hello");

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

一旦你的程序导致了这个UB,所有的赌注都会被取消,并且任何行为都是可能的。

你需要:

char *s = new char [strlen("hello") + 1];

事实上,理想的解决方案是使用std::string而非char * 。这些是std::string避免的错误。在您的示例中,没有必要使用char *代替std::string 使用std::string

  • 您不需要new任何
  • 您不需要delete任何事情&
  • 您可以使用std::string执行所有操作,使用char *

答案 1 :(得分:13)

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

答案 2 :(得分:9)

strcpy包含空终止符; strlen没有。写:

char *s1 = new char [strlen(s) + 1];

答案 3 :(得分:6)

来自人strcpy(3)

  

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

因此,您需要为字符串保留6字节5,为1字节保留NULL

char *s = new char [6];
strcpy(s, "hello");

答案 4 :(得分:3)

到目前为止,所有答案都已解决了第一次或第二次分配。总而言之,您必须进行两次更改:

char *s1 = new char [strlen(s) + 1];
...
char *s = new char [5 + 1];

在这两种情况下,您必须为字符串分配足够的空间,并为终止'\ 0'分配一个字节。

正如其他人已经指出的那样,使用c ++,使用std::string会更容易,更安全。没有分配和释放内存或注意'\ 0'字节:

std::string ff (const std::string &s){
    std::string s1(s);
    // do something else with s1
    return s1;
}

int main(int argc, char* argv[])
{
    std::string s("hello");
    std::string s2 = ff(s);
    return 0;
}

如果它只是复制字符串:

std::string s("hello");
std::string s2(s);

答案 5 :(得分:1)

您需要指定char *s1 = new char [strlen(s) + 1];以便为终止字符串的'\0'腾出空间。

答案 6 :(得分:0)

您的初始字符串s只有五个字符长,因此无法终止。 "hello"strcpy复制strlen,包括空终止符,但您将超出缓冲区。 std::string需要将其终止,所以如果null不在那里,你就会遇到问题。尝试更改此行:

char * s = new char [6];

更好的是,更喜欢new到C风格的字符串函数 - 它们效率更高,更安全,更易于使用。另外,请尽量避免使用delete和{{1}},除非您真的必须使用它们。你遇到的问题很常见,很容易避免。

答案 7 :(得分:0)

你已经通过

破坏了s2指针
strcpy(s, "hello");

因为s的大小为5,而你错过了strcpy包含字符串终止符。