为什么在这里返回malloc指针导致“HEAP CORRUPTION”免费?

时间:2011-09-15 00:00:17

标签: c++ c string memory-management

注意:请取消关于“C ++?使用std :: string!”的评论。这个问题是使用C字符串,但更多的是关于内存管理而不是字符串。

我有这个功能

char* strclone( char* src )
{
    char* dst = (char*)malloc(strlen(src+1));
    strcpy(dst,src);
    return dst;
}

该函数应该用于分配新指针(在strclone中),在src中写入字符串,并返回新字符串的地址。

但是,当字符串为free d时,稍后在程序中:

str = strclone( some_str_variable );    
// ..code..
free( str ) ; //! ERROR!  

错误如下:

调试错误! 节目:C:\ ... HEAP CORRUPTION DETECTED:在正常块(#39713)之后的0x090CC448处。 CRT检测到应用程序在堆缓冲区结束后写入内存。

错误发生在我在程序中调用free( str )的行。如果我将str的赋值更改为:

str = (char*)malloc( strlen( some_string_variable ) +1);
strcpy( str, some_string_variable ) ;
//...
free( str ) ; //fine now

然后没有错误,程序运行完美。

为什么strclone功能无法按预期工作?

5 个答案:

答案 0 :(得分:15)

我认为问题在于你已经写过了

(char*)malloc(strlen(src+1));

请注意,在致电strlen时,您已写过

strlen(src + 1)

而不是

strlen(src) + 1

第一行表示“字符串的长度超过src”,这是字符串的长度减去1(如果字符串为空则为总垃圾)。第二个是你想要的那个 - 字符串的长度加上一个空终止符。如果您使用的是第一个版本,那么就行

strcpy(dst,src);

您将最终写入缓冲区的末尾,导致可怕的未定义行为。在您的情况下,当您尝试释放块时,这表现为堆损坏错误,这是有道理的,因为您确实已经损坏了堆!

尝试从括号中移出+1,看看它是否修复了问题。

或者,大多数编译器都附带一个名为strdup的非标准函数,它完全按照上面的函数执行的操作。您可能想要考虑使用它。

希望这有帮助!

答案 1 :(得分:3)

strlen(src+1)strlen(src)+1不同。所以当你对strcpy进行覆盖时,你会用两个元素覆盖数组的边界。

所以我认为以下是合理的: C ++?使用std::string

答案 2 :(得分:0)

试试这个:

malloc(strlen(src)+1);

答案 3 :(得分:0)

我相信你应该输入

char* dst = (char*)malloc(strlen(src) + 1);

而不是

char* dst = (char*)malloc(strlen(src+1));

答案 4 :(得分:0)

发生错误是因为您实际上正在写入已分配的内存。 将malloc行更改为:

char* dst = (char*)malloc(strlen(src)+1);

因为在您的原始实现中,您将指针前进1,然后将其传递给strlen(),这将为您提供字符串-1的长度。由于你最后还需要NULL,所以你实际上是2分。