web-dev-qa-db-ja.com

C ++の文字列リテラルは静的メモリで作成されていますか?

C++の文字列リテラルは静的メモリで作成され、プログラムの終了時にのみ破棄されますか?

43
yesraaj

それが作成される場所は、実際には、コンパイラの作成者による実装の決定です。ほとんどの場合、文字列リテラルは変更されないため、メモリの読み取り専用セグメントに格納されます。

昔のコンパイラの時代には、これらのリテラルのような静的データと、グローバルであるが変更可能なデータがありました。これらは、TEXT(コード)セグメントとDATA(初期化データ)セグメントに格納されていました。

_char *x = "hello";_のようなコードがある場合でも、hello文字列自体は読み取り専用メモリに格納され、変数xはスタックにあります(または、書き込み可能なメモリのどこかにあります。グローバル)。 xは、hello文字列のアドレスに設定されます。これにより、文字列の折りたたみなど、あらゆる種類のトリッキーなことが可能になり、「無効なオプション」(0x1000)と「有効なオプション」(0x1002)が次のように同じメモリブロックを使用できるようになります。

_+-> plus:0   1   2   3   4   5   6   7   8   9   A   B   C   D   E
|      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+----+
0x1000 | i | n | v | a | l | i | d |   | o | p | t | i | o | n | \0 |
       +---+---+---+---+---+---+---+---+---+---+---+---+---+---+----+
_

ROMの観点からは読み取り専用メモリを意味するのではなく、変更できないもの(OSによって実際に読み取り専用とマークされる場合があります)を格納するための専用メモリを意味することに注意してください。

また、main()が終了するまで破棄されることはありません。

43
paxdiablo

はい、文字列リテラルは、静的オブジェクトの破棄中であっても、プログラムの全期間にわたって有効です。

標準の2.13.4/1は言う

通常の文字列リテラルのタイプは「arrayofnconstchar」で静的ストレージ期間です。

標準では、3.7.1/1の「静的ストレージ期間」について次のように述べています。

これらのオブジェクトのストレージは、プログラムの期間中存続するものとします。

46
James Hopkin

はい、そうです。彼らはある種でなければなりません。各文字列の文字シーケンスを構成する情報は、どこかにある必要があります。それらが動的に割り当てられてから初期化される場合、初期化に使用される情報はどこにありますか?したがって、単純に文字列を静的にする方が効率的であり、プログラムのロードが完了すると、文字列は常に使用可能で有効になります。

3
unwind