为什么这段代码会泄漏?

时间:2012-05-31 19:47:12

标签: c++ ios memory memory-management memory-leaks

好了,再次,这次编译器向我显示内存错误(泄漏):

  

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; 
        }

由于

3 个答案:

答案 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;
}