2

私が前任者から受け継いだプログラム全体を通して、次の形式の関数があります。

    somefunc(some_type some_parameter, char ** msg)

つまり、最後のパラメーターは、char **メッセージを返すために使用される です。つまり: somefunc()will "change" msg. 場合によっては、問題の変更は次の形式になります。

    sprintf(txt,"some text. Not fixed but with a format and variables etc");
    LogWar("%s",txt);   //call to some logging function that uses txt
    *msg = strdup(txt);

への各呼び出しには、割り当てられたメモリを解放するためstrdup()の関連する呼び出しが必要であることを知っています。free()

そのメモリは何かを返すために使用されるため、明らかに最後に解放されるべきではありませんsomefunc()

しかし、どこで?

が同じsomefunc()メッセージで複数回呼び出された場合、そのポインターは動き回ると思います。の呼び出しで割り当てられたスペースは失われますよね?

プログラムの終了前のどこかで、私は確かにすべきfree(*msg)です。(この場合*msg、 への呼び出しでパラメーターとして使用されるバージョンです。)しかし、その呼び出しは、への以前の呼び出しで割り当てられたメモリではなく、最後somefunc()に割り当てられたメモリのみを解放すると思いますよね?somefunc()

だから、私はそれsomefunc()が次のようになるべきだと言っているのは正しいですか:

    sprintf(txt,"some text. Not fixed like here, but actually with variables etc");
    LogWar("%s",txt);   //call to some logging function that uses txt
    free(*msg); //free up the memory that was previously assigned to msg, since we will be re-allocating it immediatly hereafter
    *msg = strdup(txt);

そのため、 のfree() strdup().

私は正しいですか?

4

1 に答える 1

1

はい、あなたは正しいです。から返された古いポインターは、上書きする前に d にするstrdup()必要があります。そうしfree()ないと、メモリ リークが発生します。

明確にするためにどこが単純であるかは確かですが、もちろん、次のようなものに投票します。

const char * set_error(char **msg, const char *text)
{
  free(*msg);
  *msg = strdup(text);
}

その後:

LogWar("%s",txt);   //call to some logging function that uses txt
set_error(msg, txt);

カプセル化を使用して、この非常に重要なシーケンスをより明確に定義し、名前を付けた方法をご覧ください。

于 2012-09-04T12:13:07.807 に答える