2012-01-01 29 views
30

私は時間/日の機能に役立つtime.hのファイルをCで再生していました。ローカルタイムの結果構造体はC言語でどのように割り当てられていますか?

私が出会った:

struct tm * _Cdecl localtime(const time_t *__timer); 

...のtm構造体へのポインタを返すように思われます。私はアドレスによる返却が主に新しいメモリ割り当てを返すために使用されることを発見しました。

この場合、実際には上記の返品はどのように機能しますか(返品先住所はstruct tm)。返されるオブジェクトはどこかで定義されていますか?

おかげ

+0

あなたのコードには、***構造体***を定義して割り当てます。*** localtime()はその構造体に出力を格納し、同じ構造体へのポインタを返します。これは重複しているように見えるかもしれませんが、構造体がどこにあるのかを知っていても、ポインタを戻すことは時々便利です。 –

+3

@PeteWilson - ええええええええええええ、あなたはありません。以下の回答をご覧ください。あなたが記述しているのは、SUSv2からの '_r'バージョン(' localtime_r() ')やMSVCの' _s'バージョンの場合だけです。 –

+0

[localtime()の返された構造体は、解放される?](http://stackoverflow.com/questions/6210880/does-returned-struct-of-localtime-need-to-be-freed) –

答えて

37

localtime(およびいくつかの他の関数)によって返されたポインタは実際に静的に割り当てられたメモリを指すポインタです。 だから解放する必要はありません。さらに、あなたはそれを解放すべきではありません。

http://www.cplusplus.com/reference/clibrary/ctime/localtime/

この構造は、静的関数 のgmtimeとLOCALTIMEによって割り当てられ、共有されています。これらの機能のいずれかが と呼ばれるたびに、この構造の内容が上書きされます。

編集:コメントに記載されているいくつかを追加します。

この共有データ構造の直接の結果はlocaltimeであり、同様の機能はスレッドセーフではないということです。スレッドセーフなソリューションは、プラットフォームによって異なります。 localtime_r for POSIXおよびlocaltime_s for MSVC

+1

+1。 –

+5

@OliCharlesworth実際には、(C99,7.33.3時間変換関数)を読んでいる "strftime関数を除いて、これらの関数はそれぞれポインタを返す。 2つのタイプの静的オブジェクトのうちの1つ[...]これらのオブジェクト型のいずれかへのポインタを返す関数の実行は、以前の呼び出しから返された値によって指し示される同じ型のオブジェクトの情報を上書きする可能性があります。それらのいずれか。 – ouah

+1

これは、スレッドセーフではないことと、これらの呼び出しの '_r'バージョンがそうであることを指摘しておいても良いでしょう。 –

3

実際にはlocaltimeは、通常、静的オブジェクトのアドレスを返します。

struct tm * 
localtime(const time_t *timer) 
{ 
    static struct tm tm; 

    /* Magic. */ 

    return &tm; 
} 
+0

あなたがいなくなっています – ChrisWue

+1

@ChrisWue bk1eは既に編集済みです:-) – cnicutar

+0

Cにはオブジェクトがありません: –

11

それは静的に割り当てられたメモリ(おそらくlocaltime内で定義されstatic変数またはどこかCランタイムライブラリで定義されたグローバルのいずれか)の作品へのポインタを返します。私はそれがこのようになります疑い。あなたはそのような記憶を解放してはいけません。

明らかに、この関数はリエントラントではありません(ただし、TLSを使用する場合はスレッドセーフです)。

このポインタを使用するときは注意する必要があります:/ localtime/gmtimeを呼び出すことができます任意の関数呼び出しを行うことはありません...あなたがそのポインタの使用を終了する前に、そうでない場合は、あなたのポインタが参照するメモリの内容が応答で(変更される可能性がlocaltimeへの新規呼び出し)、別のtime_tとの相対的な値が読み取られます。

一般に日付/時刻ライブラリのデザインはかなり時代遅れです。この種の最適化は、C言語の設計時には価値がありました。 localtime_r(SUSv2では、「リエントラント」のr滞在)とlocaltime_s(マイクロソフト、「安全」のためのs滞在):これらの機能のうちの少なくとも二つの異なる改善のバージョンが存在するこれらの問題に対処するために

。悲しい事実は、移植性のため、これらはほぼ同じことです(パラメータとして渡される宛先はstruct tmです)が、パラメータの名前と順序が異なります。

+0

注: 'localtime_s()'もC11仕様で詳述されています:規範セクションK.3.8.2.4。 MS(または誰か)がそのC11仕様を満たしているかどうかは不明です。 – chux

5

man pageは言う:

日時関数のいずれかへのその後の呼び出しによって上書きされる可能性が静的に割り当てられた構造体への戻り値のポイント。また

localtime_r()も同様行いますが、ユーザが提供する構造体にデータを格納します。 tzname、timezone、およびdaylightを設定する必要はありません。

0

localtime関数によって返される尖ったオブジェクトは、静的な記憶期間を持ちます。

3

ライブラリに対してローカルな静的構造体へのポインタを返します。マニュアルページから:

NOTES 

The four functions asctime(), ctime(), gmtime() and localtime() return 
a pointer to static data and hence are not thread-safe. Thread-safe 
versions asctime_r(), ctime_r(), gmtime_r() and localtime_r() are spec‐ 
ified by SUSv2, and available since libc 5.2.5. 

POSIX.1-2001 says: "The asctime(), ctime(), gmtime(), and localtime() 
functions shall return values in one of two static objects: a broken- 
down time structure and an array of type char. Execution of any of the 
functions may overwrite the information returned in either of these 
objects by any of the other functions." This can occur in the glibc 
implementation.
+0

+これは、スレッドセーフなバージョンに言及するためのものです。 – Mysticial

+0

マニュアルページは素晴らしいことです。当時私はそれ以外の誰かが答えたので私は私が関連する文書を投稿するだけだと思った私には表示されませんでした。 –

関連する問題