【发布时间】:2012-06-06 02:30:41
【问题描述】:
好吧,又来了,这次编译器向我显示了一个内存错误(泄漏):
otest(18015,0xacae32c0) malloc: * 对象 0x194e734 错误: 已释放对象的校验和不正确 - 对象可能已被修改 被释放后。 * 在 malloc_error_break 中设置断点进行调试
我正在使用激活 ARC 和 STL 的 clang,这是一个 C++ 文件 (.cpp)。
我的发现:如果我评论“删除”行,它运行没有问题。这让我想知道是谁在释放我分配的内存 (cStr)。
顺便说一句。此代码采用查询字符串 (arg=abc&arg2=asdb) 并返回包含这些值的映射。
static map<string, string> getDecodedQueryString( string qs ) {
map<string, string> r;
qs = qs+"&";
char key[100], value[100], * cStr, *ptr;
cStr = new char[ qs.length() ];
memcpy( cStr, qs.c_str(), url.length()-1);
cStr[qs.length()]=0;
ptr = strtok(cStr, "&");
while ( ptr != NULL && sscanf( ptr, "%[^=]=%[^&]", &key, &value ) == 2) {
r[key]=value;
ptr = strtok(NULL, "&");
}
delete [] cStr; //leaking?
return r;
}
谢谢
【问题讨论】:
-
什么是
url.length(),它与qs.length()有什么不同?如果url比qs长(我怀疑可能是这样),那么您将覆盖已分配缓冲区的末尾。 -
该错误表明它不是泄漏,而是对已释放内存的过时引用。
-
new char[ qs.length() ]没有分配足够的内存来保存终止符。解决这个问题并开始使用 std:vector 和/或 std::array ,你就可以上路了。 -
strtok 确实修改数据。但是,因为您所做的是 UB,它也可能工作,或者看起来像它工作。在 C++11 中,您可以使用 string::data,因为它也保证是 nul 终止的。 (与此同时,您可以将 NUL 附加到字符串,因为它只是一个局部变量。)
标签: c++ ios memory memory-management memory-leaks