1

ソースコードをチェックしていたところ、次のforループが見られました。

for (int i=0; i < result1.length(); i++) {
    unsigned char *buff = ascii_to_utf8((unsigned char)result1.at(i));
    result.append((char*)buff);
    free (buff);
}

これに変更されました:

for (int i=0; i < result1.length(); i++)
    result.append((char*)ascii_to_utf8((unsigned char)result1.at(i)));

私が見ることができる唯一の違いは、2 番目のコードには中間変数がないことです。

私の質問は、私が見ることができなかった 2 つのコード スニペットに違いはありますか? freeセカンドコードには何もありませんか?

------------ 編集 ----------- ascii_to_utf8 のソース コードは次のとおりです。

unsigned char* InvoiceXML::ascii_to_utf8(unsigned char c)
{
    unsigned char *out;

    if(c < 128)
    {
        out = (unsigned char *)calloc(2, sizeof(char));
        out[0] = c;
        out[1] = '\0';
    }
    else
    {
        out = (unsigned char *)calloc(3, sizeof(char));
        out[0] = (c >> 6) | 0xC0;
        out[1] = (c & 0x3F) | 0x80;
        out[2] = '\0';
    }

    return out; 
}
4

3 に答える 3

3

ascii_to_utf8が何をするかによります。ほぼ確実にメモリを割り当てます。その場合、そこに「空き」が必要です。したがって、2番目のスニペットはメモリリークを起こします。

于 2012-12-06T15:26:52.387 に答える
1

がメモリを割り当てないように変更された場合ascii_to_utf8(たとえば、結果に静的な char 配列を使用することによって)、呼び出し元は戻り値を削除しないでください。

于 2012-12-06T15:44:38.867 に答える
1

ascii_to_utf8がメモリを割り当てる場合:

最初のスニペット:resultオブジェクトが関数内でコピーされないappend場合、それは明らかに間違っています。解放された値へのポインターを格納しようとしています。

2 番目のスニペット:resultオブジェクトが関数内でコピーするappend場合、それは間違っています。そうでないfree()場合は、そのデータをどこかに保存する必要がありますが、このスニペットは正しいです。

また、`ascii_to_utf8を介してメモリを割り当てる場合は、代わりにnew使用する必要がありますdelete

それ以外の場合 (ascii_to_utf8メモリを割り当てません):

free最初のスニペットは間違っています -メモリを静的に割り当ててはいけません。

2 番目のスニペットは正しいです。

于 2012-12-06T15:44:38.993 に答える