• ベストアンサー

ポインタを定義したらなぜsizeofで容量が表示できる?

char *sz と定義しても実体はメモリに確保されていないはずなのに なぜ printf("%d",sizeof(*sz))でちゃんと1が表示されるんでしょうか? また、 sz = malloc( 100 )で printf("%d",sz)で100ではなく4となってしまうのはなぜですか? よろしくお願いします。

noname#141207
noname#141207

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

■なぜprintf("%d",sizeof(*sz))でちゃんと1が表示されるんでしょうか? sizeof演算子はプログラム実行時に()内の計算を行っているのではなく、 コンパイル時に()内のメモリのサイズを数値に置き換えるものです。 つまり、  sizeof(*sz) は sizeof(*(char*))  sizeof(*(char*)) は sizeof(char) と、コンパイラが判断し、 sizeof(*sz)が「1」という数値に置き換えられます。 #defineみたいなものだと思ってもいいです。 質問者さんの書いた  printf("%d",sizeof(*sz)) という文はコンパイルに掛けられた時点で  printf("%d",1) というように置き換えられてプログラムは実行されてしまいます ■printf("%d",sizeof(sz))で100ではなく4となってしまうのはなぜですか? 例えば、char c[100]と定義してsizeofを使うと  sizeof(c) = sizeof(char[100]) = 100byte と、ちゃんと「100byte分のメモリサイズですよ」と認識はしてくれます。 これはコンパイルした時点でchar型変数100個分の配列だと決まっているからです。 が、ポインタの指しているアドレスがどれくらいのメモリサイズを持つものかは コンパイルの時には決まっていないのでわからないのです。 ■sz=malloc(100)で100を表示させる方法はありますか? 使用環境によっては使えないかもしれませんが、  size_t _msize( void* memblock ) というmalloc等で確保したメモリのサイズを返してくれる便利な関数があります。

その他の回答 (3)

  • notnot
  • ベストアンサー率47% (4847/10260)
回答No.3

sizeof(*sz) は、sz の指した先のサイズです。コンパイラは、char *sz; という宣言から、szの指した物はcharだとわかるので、そのサイズである1になります。ポインタ変数szの中を中を見るわけじゃないので、実体が割り当てられているかどうかには無関係です。 >printf("%d",sz)で100ではなく4となってしまうのはなぜですか? おそらく、printf("%d",sizeof sz)の書き間違いだと思いますが、ポインタ変数szのサイズはポインタ自体のサイズなので、32bit系コンパイラでは4になります。 sizeof演算子は、プログラム実行時じゃなくてコンパイル時にわかる「型のサイズ」「変数のサイズ」を求める演算子です。動的に割り当てたメモリ領域の大きさを調べてくれる関数じゃないです。 sizeof *sz で、100が得たければ、こんな感じにするしかないですね。 typedef char buf[100]; buf *sz; printf("%d\n",sizeof *sz);

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

まずprintf("%d",sz)なら これはポインタ変数のアドレスを10進表示しますので、 sz = malloc( 100 )後ならもっと複雑な数値となるはずです。 malloc前なら値は不定ですので何が表示されるか分かりません。 printf("%d",*sz)だと話は変わります。 ポインタ参照していますので、ポインタが指すアドレスの先のメモリ100バイトの1バイト目を参照する事になります。mallocしたままだと値は不定ですので何が表示されるかは分かりません。 >また、sz=malloc(100)で100を表示させる方法はありますか? ありません。ポインタ変数はサイズを保持しないのでサイズが欲しかったら別変数に記録しておくことが必要です。 ちなみにC言語の標準関数で、アドレスからmallocしたメモリのサイズを調べる方法もありません。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

なかなか良いところに気づきました。 これが変数とポインタ変数の違いです。 sizeofは変数のメモリサイズを求めます。 sizeof(*sz) はcharポインタ型のサイズですので、ポインタ変数が4バイトのサイズであるって意味です。つまりアドレス値を保持するのに4バイト使っていると言うことです。 sz = malloc( 100 )でmallocしてもポインタ変数のサイズが変わるのではなく、ポインタ変数の指すアドレスの先のメモリが100バイト確保されただけです。 分かりますかね?

noname#141207
質問者

お礼

ご回答ありがとうございます。 イマイチわからないですね・・・ 4バイトが表示されるのはまだ納得がいきます。 ポインタの領域を確保しているのですから。 printf("%d"*sz)で1が表示されるのが分からないです。 また、sz=malloc(100)で100を表示させる方法はありますか? よろしくお願いいたします。

関連するQ&A

  • ポインタの場合のsizeof()

    C言語の基礎かもしれませんが、質問させてください。 例えば char a[20] = "computer program"; printf("%d",sizeof(a)); とすると、char型なのでおそらく16と出力されると思うのですが、 char *a = "computer program"; と定義したとき、 printf("%d",sizeof(a)); とすると、どんな値が表示されるのでしょうか?

  • sizeofとポインタ

    char *p; printf("%d",sizeof(*p)); これでなぜ1が出力されるのか分かりません。お願いします。

  • ポインタのsizeofについて

    C初心者です。 ポインタ宣言させた変数をsizeof()で値を取得させて 表示させてみました。 char *cp; short int *sp; int *ip; i = sizeof(cp); printf("%d\n",i); i = sizeof(sp); printf("%d\n",i); i = sizeof(ip); printf("%d\n",i); 結果は全て4となりました。 これはなぜですか? (ただの変数として宣言すれば1、2、4となります。この理由も理解できています。)

  • sizeof

    main() { char array1[256] = "abcdefg"; char *array2 = "stuvwxyz"; printf("array1 = %d\n",sizeof(array1)); // array1 = 256 printf("array1 = %d\n",sizeof(array1)/sizeof(char)); // array1 = 256 printf("array2 = %d\n",sizeof(array2)); // array2 = 4 printf("array2 = %d\n",sizeof(array2)/sizeof(char *)); // array1 = 1 printf("array2 = %d\n",sizeof(*array2)); // array2 = 1 } となるのですが、sizeof(array1)では、配列のサイズが取得できるのですが、array2がさす配列のサイズを得るためにはどうすればいいのですが?もしくは取得デキナイのはなぜでしょうか。 それと、 sizeof(array2)では、charへのポインタをさすから4バイト。 sizeof(*array2)では、sizeof(array[0])を意味するから1バイト という解釈でいいでしょうか。

  • sizeof が分かりません!

    Cの予約語で"sizeof"がありますが、 普段おきまりで良く使っているのですが、 いまいち理解出来ないので誰か教えて下さい。 例えば、以下の場合sizeofの結果はどうなりますか? char s_aaa[]="ABCDE"; char s_bbb[4]; memset(s_bbb, '\0', sizeof(s_bbb)); memcpy(s_bbb, s_aaa, sizeof(s_bbb)); printf("s_aaa → :[%d],[%d]\n", strlen(s_aaa), sizeof(s_aaa)); printf("s_aaa → :[%d],[%d]\n", strlen(s_bbb), sizeof(s_bbb));

  • ポインタ配列の動的確保

    ポインタの配列の動的確保について教えてください。 入力した数値をポインタ配列に入れるプログラムです。 下記のように書いてみました。(見づらくてごめんなさい) #include<stdio.h> #include<stdlib.h> #define kensu 3 main() { char abc[kensu+1]={'A','B','C','\0'}; char *ptr[kensu]; int i; printf("3つの整数を入力して下さい。\n"); for(i=0;i<kensu;i++){ ptr[i]=(char*)malloc(sizeof(char)*10); if(ptr[i]==NULL){ printf("メモリの取得に失敗しました"); exit(1); } printf("整数%c:",abc[i]); fgets(ptr[i],10,stdin); if(ptr[i][strlen(ptr[i])-1]=='\n') ptr[i][strlen(ptr[i])-1]='\0'; } for(i=0;i<kensu;i++) free(ptr[i]); } ちゃんと動いているようです。 しかし、ポインタ配列の動的確保をネットで調べてみると、ポインタのポインタ(?)を使って、下記のように2度mallocしています。 #include <stdio.h> #include <stdlib.h> #define N 3 int main(void) { char** arr; int i,j; arr = (char**)malloc(N * sizeof(char*)); /* ポインタ配列を確保 */ /* 配列の要素それぞれにつき、メモリ領域を確保 */ for(i=0;i<N;i++) arr[i] = (char*)malloc(N * sizeof(char));   ・・・ ポインタの配列を宣言して、配列の各要素に動的確保するのと ポインタのポインタを宣言し、ポインタ配列を動的確保して、再度配列の要素に動的確保するのとでは、何か違いがあるのでしょうか? ポインタのポインタを宣言し、ポインタ配列を確保する必要性が良く分かっていないのです。 ネット等で調べて見たのですが、理解力がないのかよく分かりませんでした。 どうか教えてください。

  • ポインタ変数のサイズ

     いろいろC言語のことを知りたくて、次のソースを作って動かしてみました。 ★ソース(□はタブ) ◆◆◆◆◆ #include <stdio.h> #include <stdlib.h> int main(void) { □char *s1; □int *s2; □ □s1 = (char *)malloc(1000); □s2 = (int *)malloc(1000); □ □printf("sizeof s1 = %d\n", sizeof s1); □printf("sizeof s2 = %d\n", sizeof s2); □ □printf("sizeof *s1 = %d\n", sizeof *s1); □printf("sizeof *s2 = %d\n", sizeof *s2); □ □printf("s1 = %d\n", s1); □printf("s2 = %d\n", s2); □ □printf("*s1 = %d\n", *s1); □printf("*s2 = %d\n", *s2); □ □return EXIT_SUCCESS; } ◆◆◆◆◆ ★実行結果1 ◆◆◆◆◆ sizeof s1 = 4 sizeof s2 = 4 sizeof *s1 = 1 sizeof *s2 = 4 s1 = 1323000 s2 = 1324008 *s1 = -60 *s2 = 1310916 ◆◆◆◆◆ ★実行結果2 ◆◆◆◆◆ sizeof s1 = 4 sizeof s2 = 4 sizeof *s1 = 1 sizeof *s2 = 4 s1 = 11087864 s2 = 11088872 *s1 = -60 *s2 = 11075780 ◆◆◆◆◆ ★実行結果3 ◆◆◆◆◆ sizeof s1 = 4 sizeof s2 = 4 sizeof *s1 = 1 sizeof *s2 = 4 s1 = 1519608 s2 = 1520616 *s1 = -60 *s2 = 1507524 ◆◆◆◆◆  OSはWindows Vista、コンパイラはMS Visual Studio 2010 コマンドプロンプトです。次の疑問についてご教授頂きたく、お願い致します。 (1)“sizeof s1”、“sizeof s2”の値が共に4となるのはなぜか。  char型へのポインタ、int型へのポインタとして宣言したs1、s2のサイズが同じ4になる理由が、どうしても分かりません。 (動かす前の予想は、でたらめな値になるかと思っていましたが) (2)“s1”、“s2”、“*s2”の値が毎回でたらめな値になったのに対して、“*s1”の値が毎回“-60”になったのはなぜか。  ポインタでつまずいており、いろいろ実験して体で理解したいと思っています。どうぞよしくお願い致します。

  • Sizeofが分かりません

    sizeofのデータサイズがどういう風に計算されているのかよく分かりません。 例えば以下のコードですが、 union Name { char firstName[10]; char lastName[10]; }; int main() { union Name name; strcpy(name.firstName, "Dennis"); strcpy(name.lastName, "Ritchie"); printf("%d", sizeof(name)); } outputは11となります。これはなぜでしょうか? 宜しくお願い致します。

  • sizeof()の使い方

    あるプログラムでちょっと珍しいソースコードがありました。 *************************************************************** int x[7]; int nx = sizeof(x) / sizeof(x[0]); for (i = 1; i < nx; i++) { -省略- } *************************************************************** sizeof()という珍しい関数を使っています。 このプログラムの目的は、sizeof()を使って、forの繰り返し回数を算出して、 プログラマー側がアルゴリズムを考えて、forの繰り返し回数を設定する手間を省いてくれることにあります。 しかし、ちょっとおかしな事がありまして、 printf("sizeof(x)="); printf("%d\n",&sizeof(x)); printf("sizeof(x[0])="); printf("%d\n",&sizeof(x[0])); printf("nx=sizeof(x) / sizeof(x[0]):"); printf("%d\n",&nx); を使って、sizeof(x),sizeof(x[0]),nxに何が設定されたかを確かめたところ、 sizeof(x)=28 sizeof(x[0])=7 nx=1638196 と分かりました。nxは”7”でないとおかしいと思うのですが、いかがでしょうか?

  • ポインタ操作について

    C言語から離れている間にmallocの使い方がいまいちわからなくなってしまいました。 基本的な質問となりますが御教授ください。 (1)char **a の時 (2)char *a[10] の時 (3)char a[][10] の時 それぞれのメモリの確保の方法、解放の方法を御教授ください。 できれば、確保後のアクセス方法等も御教授ください。 上記したソースのような例を書いて頂けると幸いです。 サンプルrサイトでも結構です。 例えば、簡単な例を出すと・・・(間違っているかもしれないですが) (0)char *aの場合 /***************************************/ void kansuA(char a){ : } void kansuB(char *a){ : } //////////////////////////////////////// int main(int){ char *pa; pa = (char *)malloc( sizeof(char)*5 ); // 確保 memset(pa,0x00,sizeof(char)*5); strncpy(pa,"1234",4); kansuA(pa); // 値渡し kansuB(&pa); // アドレス渡し free(a); //解放 } /***************************************/ 宜しく御願致します。

専門家に質問してみよう