2011-01-13 13 views
31

メモリ割り当ての点で、これら2つの違いは何ですか?メモリ割り当てchar *とchar []

char *p1 = "hello"; 
char p2[] = "hello"; 
+13

最初は 'const char *'です。 – rubenvb

+0

'p1'は、プラットフォームに依存する4または8バイト(メモリアドレスの格納に必要)を要します。 'p2'は6バイト(文字列' hello'では5バイト+ヌル終了文字では1バイト)をとります。 – RBT

答えて

35

最初のものは、以下を含む(第2の一方はアレイ 6の文字を作成し、そこに文字列リテラルの位置ポインタ変数(プラットフォームによってストレージの4または8バイト)を作成して記憶しますゼロストリングターミネーターバイト)、そのリテラルをそこにコピーします。

リテラルはconstなので、最初の行でコンパイラの警告が表示されます。

+0

正確に文字列リテラルが格納されていますか?それはヒープですか? – blitzkriegz

+10

文字列リテラルは、通常、スタックと( 'new' /' delete'管理された)ヒープとは別のメモリ領域に格納されます。プラットフォームによっては、この領域がコピープロテクトされている可能性があります。この領域に書き込むと、プログラムがクラッシュします。 –

+0

クリスタルクリアな答えに感謝します。 – blitzkriegz

8

最初のものはconst(読み取り専用)データへの非constポインタです。第2のものは非const配列です。

+0

char * p1 = "hello"はchar const * p1 = "hello"と同じですか? – blitzkriegz

+3

@Mahatma:はい、これは読みやすく直感的なバージョンの 'const char * p1 =" hello "'と同じです。 –

+2

@Mahatma:はい、最初ですが危険です: 'const'修飾がなければ、文字列リテラルを修正しようとするとコンパイラの保護がなくなり、未定義の動作が起こります。 –

6

最初のものは(読み取り専用)データをCONSTする非constポインタであるので、第二は、パウロが言ったように、あなたが書くことができ、非const配列である:

p2[2]='A'; //changing third character - okay 

しかし、あなたがすることはできません書き込み:

p1[2]='A';//changing third character - runtime error! 
+1

2番目のケースは実際にはコンパイルエラーより悪いです。コンパイラはそれを受け入れ、未定義のランタイム動作を与えます。 –

+1

これは真実ではありません。文字列リテラルはconstではないため、コンパイルエラーは発生しません。彼はしかし、UBを得るでしょう。 – Puppy

+0

@DeadMG:fixed .-) – Nawaz

関連する問題