2012-01-21 3 views
2

私は、文字列を使用している場合:'sizeof'を文字列に適用すると、サイズ(strlen)が返されるのはなぜですか?

char s1[]="hello, how are you?"; 
printf("%d\n",sizeof(s1)); 

それは文字、20の正確な、右の数値を表示します。しかし、私はポインタで初期化された文字列を持っている場合:

char *s2; 
s2=(char*)malloc(sizeof(char)); 
strcpy(s2,s1); 
printf("%d\n",sizeof(s2)); 

それはのサイズを出力しますマシンに依存するポインタ(鉱山では、8)。 なぜ、それらは同じ文字列なので、s2は8バイト、s1は20バイトですか?

答えて

10

これらは同じ文字列ではなく、同じタイプでもありません。 char s2[]の配列であり、その要素のサイズの合計のサイズを持ちます。 char *s2ポインタであり、ポインタのサイズを有する。

sizeof()は、(C89では)コンパイル時に引数のサイズを知る必要があるコンパイル時の演算子です。 ポインタはどこからでも来ることができるので、sizeof()は割り当てられたメモリのサイズを知ることができませんが、の配列は常にコンパイル時にサイズを与えられます(C99のVLAを除く)。そしてsizeof()はその記憶。

+0

コンパイル時にs2 []のサイズが分かっていますが、メモリの場所は変更できません。別のメモリ位置にs2を再割り当てしようとすると、エラーが発生します。場所はランタイムに決定されます。そのため、私は今理解しています。 –

3

配列はポインタではないことに注意してください。ある場合は配列のサイズを取得し、もう1つの場合は配列のサイズを取得します。

文字列に適用されたsizeof演算子は、末尾のヌル文字を含む文字列の文字数を返します。

2番目のケースでは、文字列のサイズを計算するのではなく、文字列へのポインタのサイズを計算するので、ポインタ型のサイズが得られます。

char *s2; 
s2=(char*)malloc(sizeof(char)); 
strcpy(s2,s1); 

このコードは間違っています。あなたは1つの文字のための部屋を割り当てています。あなたは、文字列全体のためのスペースを割り当てる必要があります。最後に

char *s2; 
s2 = malloc(sizeof s1); 
strcpy(s2, s1); 

strlen機能(あなたはそれを言及したので)について:文字列の長さは、文字列のサイズと同じ値ではありません。文字列の長さは末尾にある文字の数です。ヌル文字を終了しますが、文字列のサイズはヌル文字を含む文字列の文字数です。

1

sizeofはあなたがデータ型は20バイトを占めていますが、char*を渡すときには、マシン語を取るchar[20]に渡す場合。渡すタイプのデータのサイズを返します。

3

char s2[]はスタック上にあり、オペレータsizeofには、delnanコメントとして静的に割り当てられた配列のサイズを測定できるオーバーロードされたバージョンがあります。

char* s2はポインタであり、割り当てられた文字列(malloc)はヒープ上にあります。

+1

私は 'char'配列に対して特別な"オーバーロード "があるとは言いません。 'char'配列に関して特別なものは何もなく、ポインタとは対照的に配列についての特別な唯一のものは、前者はコンパイル時に(VLAを無視するとコンパイル時に)サイズがあり、もちろん* sizeofは情報。 – delnan

+0

@delnan:そうです、ありがとう、それを修正します。 –

1

これは定義によるものです。 sizeof演算子を配列に適用すると、配列の長さ(コンパイル段階)でコンパイラに置き換えられます。それがポインタに適用されると、コンパイラはそれをポインタのサイズに置き換えます。

1

2番目のケース(それはmalloc(<number of characters to be stored>+1)だったはずです)で十分なメモリを割り当てなかったという事実を無視して、2つのs2は同じものではありません。

最初のケースでは、の配列があります。その文字列に初期化されている正しいサイズの配列になる特殊な文字列初期化構文を使用しています。アレイ上のsizeofのサイズは正しく表示されます(単位はchar)。

2番目のケースでは、ポインタがあります。これはポインタの大きさについて何も知らないためです。ポインタ上のsizeofはポインタのサイズを返します。32ビットマシン上では、32ビットは32ビットアドレス空間内のすべての可能なメモリ位置へのポインタを格納するのに必要な空間なので、4バイト= 32ビットです。

関連する問題