简体   繁体   中英

Why does this code leak?

Well, here again, this time the compiler is showing me a memory error (leak):

otest(18015,0xacae32c0) malloc: * error for object 0x194e734: incorrect checksum for freed object - object was probably modified after being freed. * set a breakpoint in malloc_error_break to debug

I'm using clang with ARC activated and STL, this is a C++ file (.cpp).

What I found: If I comment the "delete" line it runs without problems. It makes me wonder who is freeing my allocated memory (cStr).

Btw. This code takes a query string (arg=abc&arg2=asdb) and returns a map whit those values.

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

Thanks

The problem is likely in these lines:

    cStr = new char[ qs.length() ];
    memcpy( cStr, qs.c_str(), url.length()-1);
    cStr[qs.length()]=0;

Even without the memcpy() (which may have its own problems due to the length of url , as I mentioned above in a comment), the cStr[qs.length()] = 0 writes one byte past the end of the buffer.

If your compiler has strdup() available (it's nonstandard, but most do), you can replace this with:

cStr = strdup(qs.c_str());
// ...
free(cStr);

This saves you from having to mess around with manually allocating bytes, copying them, null terminating in the right place, etc.

Str = new char[ qs.length() ];
...
cStr[qs.length()]=0;

That write is invalid, it's one past the end of cStr . If the allocator stored a checksum right after the allocation, and checks it at delete time, you've just stomped on it.

Something along the lines of below will do the same thing.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM