C++ 为什么返回malloc';d指针在这里的结果是;“堆损坏”;免费的?
注意:请禁止评论“C++?使用std::string!”。这个问题是使用C字符串,但更多的是关于内存管理,而不是一般的字符串 我有这个功能C++ 为什么返回malloc';d指针在这里的结果是;“堆损坏”;免费的?,c++,c,string,memory-management,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中的字符串写入该指针,并返回新字符串的地址 但是,当字符串是freed时
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:\。。。
检测到堆损坏:在0x090CC448的正常块(#39713)之后。
CRT检测到应用程序在堆缓冲区结束后写入内存。
错误发生在我在程序中调用free(str)
的那一行。如果我将str的赋值更改为:
str = (char*)malloc( strlen( some_string_variable ) +1);
strcpy( str, some_string_variable ) ;
//...
free( str ) ; //fine now
这样就没有bug了,程序运行得很好
为什么strclone的
功能不能按预期工作?我认为问题在于您编写了
(char*)malloc(strlen(src+1));
strlen(src + 1)
请注意,在对strlen的调用中,您已经编写了
(char*)malloc(strlen(src+1));
strlen(src + 1)
而不是
strlen(src) + 1
char* dst = (char*)malloc(strlen(src+1));
第一行表示“从一个字符开始的字符串长度超过src
”,即字符串长度减去一(如果字符串为空,则为总垃圾)。第二个是您想要的-字符串的长度加上空终止符的长度。如果使用第一个版本,则在
strcpy(dst,src);
您将结束写入超过缓冲区末尾的内容,从而导致可怕的未定义行为。在您的例子中,当您尝试释放块时,这表现为堆损坏错误,这是有意义的,因为您确实损坏了堆
尝试将+1从括号中移出,看看它是否能解决问题
或者,大多数编译器附带一个名为strdup
的非标准函数,该函数与上述函数的功能完全相同。你可能会想只考虑使用它。
希望这有帮助 我认为问题在于你写了
(char*)malloc(strlen(src+1));
strlen(src + 1)
请注意,在对strlen的调用中,您已经编写了
(char*)malloc(strlen(src+1));
strlen(src + 1)
而不是
strlen(src) + 1
char* dst = (char*)malloc(strlen(src+1));
第一行表示“从一个字符开始的字符串长度超过src
”,即字符串长度减去一(如果字符串为空,则为总垃圾)。第二个是您想要的-字符串的长度加上空终止符的长度。如果使用第一个版本,则在
strcpy(dst,src);
您将结束写入超过缓冲区末尾的内容,从而导致可怕的未定义行为。在您的例子中,当您尝试释放块时,这表现为堆损坏错误,这是有意义的,因为您确实损坏了堆
尝试将+1从括号中移出,看看它是否能解决问题
或者,大多数编译器附带一个名为strdup
的非标准函数,该函数与上述函数的功能完全相同。你可能会想只考虑使用它。
希望这有帮助 strlen(src+1)
与strlen(src)+1不同。因此,在对strcpy执行操作时,您将用两个元素覆盖数组的边界
所以我认为以下是合理的:C++?使用std::string
strlen(src+1)
与strlen(src)+1不同。因此,在对strcpy执行操作时,您将用两个元素覆盖数组的边界
所以我认为以下是合理的:C++?使用std::string
试试这个:
malloc(strlen(src)+1)代码>尝试以下操作:
malloc(strlen(src)+1)代码>我想你应该打字
char* dst = (char*)malloc(strlen(src) + 1);
而不是
strlen(src) + 1
char* dst = (char*)malloc(strlen(src+1));
我想你应该打字
char* dst = (char*)malloc(strlen(src) + 1);
而不是
strlen(src) + 1
char* dst = (char*)malloc(strlen(src+1));
发生错误的原因是您实际上正在写入已分配的内存。
将malloc行更改为:
char* dst = (char*)malloc(strlen(src)+1);
因为在最初的实现中,将指针向前移动1,然后将其传递给strlen(),这将给出字符串的长度-1。由于最后还需要空值,因此实际上是2次关闭。发生错误的原因是您实际写入的内存超过了分配的内存。
将malloc行更改为:
char* dst = (char*)malloc(strlen(src)+1);
因为在最初的实现中,将指针向前移动1,然后将其传递给strlen(),这将给出字符串的长度-1。因为你最后还需要空值,所以实际上你的值是2。你能给出一个完整的例子来说明这个问题吗?@Oli:一行就够了,不用麻烦了!你能给出一个完整的例子来说明这个问题吗?@Oli:一行就够了,不用麻烦了!请注意,尽管断言它“更多地是关于内存管理而不是一般的字符串”,但这实际上是一个C字符串(strlen
)问题。这就是为什么C字符串如此危险;即使所有事实都指向另一个方向,也很容易让自己相信自己做得对。请注意,尽管断言它“更多地是关于内存管理,而不是一般的字符串”,但这实际上是一个C字符串(strlen
)问题。这就是为什么C字符串如此危险;即使所有事实都指向另一个方向,你也很容易说服自己你做得对。