1

次のCコードがあるとします。

void myfunction() {
    time_t     t = 0;
    struct tm  *ct;

    time(&t);
    ct = localtime(&t);
}

ご覧のとおり、この関数は変数localtimeへの新しいポインターを返します。struct tm私の知る限り、関数から返された変数が呼び出し元のコンテキストで有効であるためには、次の少なくとも1つを満たす必要があります。

  1. 返される変数は、呼び出し元のコンテキストまたは呼び出し元に関連する上位のコンテキストで宣言する必要があります。
  2. 返される変数には、ヒープに割り当てられたメモリが必要です。

私の場合、最初のポイントは当てはまらないので、2番目のポイントは満たされていると考えるのが普通です。

私は正しいですか?

ctはいの場合、それは私がそれを使用した後に変数でfreeを呼び出す必要があることを意味しますか?

そうでない場合は、少し詳しく説明していただけますか?

ありがとう!


編集:

回答から、変数が返されるコンテキストで使用可能であるという要件には、別のポイントがあるはずだと理解しました。それは静的変数でなければなりません。別の可能性はありますか?

4

3 に答える 3

2

いくつかの古いC関数は、静的バッファーへのポインターを返します。 localtimeそれらの1つです。返されたポインタをから解放する必要はありません(実際、そうすべきではありません。そうすると、プログラムをセグメンテーション違反する可能性があります)localtime

問題は、プロセススペースにバッファが1つしかないことlocaltimeであり、次の呼び出しlocaltime(別のスレッドでも)は、以前に返された結果を上書きします。これが、そのように動作するほぼすべての関数(strtok別の例)_rに、結果をユーザーから渡されたバッファーに入れてスレッドセーフにする新しいバージョンがある理由です。

于 2013-03-20T07:13:11.063 に答える
1

いいえ、解放する必要はありません。

戻り値は、gmtimeまたはlocaltimeへの後続の呼び出しによって有効性または値が変更される可能性のある内部オブジェクトを指します。

ソース

つまり、この関数の戻り値を保存する場合は、手動で別の場所に保存する必要があります。

于 2013-03-20T07:11:57.123 に答える
1

man localtimeLinuxでの逐語的:

4つの関数asctime()、ctime()、gmtime()、およびlocaltime()は、静的データへのポインターを返すため、スレッドセーフではありません。

したがって、いいえ、によって返された値を解放する必要はありlocaltime()ません。さらに、それを解放しようとしないでください。

OT:スレッドセーフを維持するために、マニュアルページには次のように記載されています。

スレッドセーフバージョンのasctime_r()、ctime_r()、gmtime_r()、およびlocaltime_r()はSUSv2で指定されており、libc5.2.5以降で使用できます。

于 2013-03-20T07:13:04.580 に答える