好了,再次,这次编译器向我显示内存错误(泄漏):
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;
}
由于
答案 0 :(得分:4)
问题很可能在以下几个方面:
cStr = new char[ qs.length() ];
memcpy( cStr, qs.c_str(), url.length()-1);
cStr[qs.length()]=0;
即使没有memcpy()
(由于url
的长度可能会有自己的问题,正如我在上面的评论中所提到的那样),cStr[qs.length()] = 0
会在结束时写一个字节缓冲区。
如果您的编译器有strdup()
可用(它是非标准的,但大部分都是),您可以将其替换为:
cStr = strdup(qs.c_str());
// ...
free(cStr);
这样可以避免手动分配字节,复制它们,在正确位置终止null等等。
答案 1 :(得分:3)
Str = new char[ qs.length() ];
...
cStr[qs.length()]=0;
该写入无效,是cStr
结束时的写入。如果分配器在分配后立即存储了校验和,并在删除时检查它,那么你只是踩了它。
答案 2 :(得分:2)
下面的内容将做同样的事情。
std::stringstream ss(qs);
std::string temp;
std::string key;
std::string value;
while(std::getline(ss, temp, '&')) {
std::stringstream equal(temp);
std::getline(equal, key, '=');
std::getline(equal, value, '=');
r[key] = value;
}