0

さて、ここでも、今度はコンパイラがメモリ エラー (リーク) を示しています。

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

ありがとう

4

3 に答える 3

4

問題は次の行にある可能性があります。

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

(コメントで前述したように、memcpy()の長さのために独自の問題がある可能性があります)がなくても、書き込みはバッファの終わりを1バイト超えて書き込みます。urlcStr[qs.length()] = 0

コンパイラがstrdup()利用できる場合(非標準ですが、ほとんどの場合は利用できます)、これを次のように置き換えることができます。

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

これにより、手動でバイトを割り当てたり、コピーしたり、適切な場所でnullを終了したりする必要がなくなります。

于 2012-05-31T19:52:03.227 に答える
3
Str = new char[ qs.length() ];
...
cStr[qs.length()]=0;

その書き込みは無効です。の終わりを過ぎたものですcStr。アロケータが割り当ての直後にチェックサムを保存し、削除時にチェックサムをチェックした場合は、それを踏みにじっただけです。

于 2012-05-31T19:51:36.287 に答える
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;
}
于 2012-05-31T20:10:59.983 に答える