char*p; p = (char*)malloc(sizeof(char*)*100);を実行した場合は400バイト分のメモリが動的に確保されます

ソーラー「それでは


お次は何が出てくるかな?


今日は


char*p;


p = (char*)malloc(sizeof(char*)*100);


は実行した場合


何バイト分のメモリが確保されることになるか考察してみたいと思います」



アレサ「ソーラーさん


malloc関数の引数を記述する()内は


sizeof(char)


でなく


sizeof(char*)


となっているのですね」


ソーラー「そうなんだよ


おもしろそうだね」



そのプログラムはこちらです

👇


#include <stdio.h>

#include <stdlib.h>//🌞malloc関数を使用するときはヘッダファイル<stdlib.h>をインクルードしてください


int main(void) {


char* p;


p = (char*)malloc(sizeof(char*)*100);



if (p == NULL) {

printf("メモリは確保されませんでした。");

}


else {

printf("メモリは確保されました。");

printf("確保したメモリの先頭のメモリのアドレスは %pです。\n", p);

}


printf("sizeof(char*)は%dです\n", sizeof(char) );

printf("確保されたメモリは%dバイトです\n", sizeof(char) * 100);


free(p);


return 0;

}


ビルド実行結果


メモリは確保されました。確保したメモリの先頭のメモリのアドレスは 00B69010です。

sizeof(char*)は4です

確保されたメモリは400バイトです


ソーラー「このプログラムでは


malloc関数により


メモリが400バイト分確保されています


p = (char*)malloc(sizeof(char*) * 100);



sizeof(char*)は一体


何かということですね


sizeof演算子とは


変数の型が何バイトの格納容量を持つかを


示すことができます


char型は1バイトのデータ容量をもつので


sizeof(char)は1


をあらわします


int型は4バイトのデータ容量をもつので


sizeof(int)は4


をあらわします


float型は4バイトのデータ容量をもつので


sizeof(float)は4


をあらわします


float型は8バイトのデータ容量をもつので


sizeof(double)は8を表します


そのプログラムはこちらです

👇


#include <stdio.h>

#include <stdlib.h>//🌞malloc関数を使用するときはヘッダファイル<stdlib.h>をインクルードしてください


int main(void) {


printf("sizeof(char)は%dバイトです\n", sizeof(char));

printf("sizeof(int)は%dバイトです\n", sizeof(int));

printf("sizeof(float)は%dバイトです\n", sizeof(float));

printf("sizeof(double)は%dバイトです\n", sizeof(double));



return 0;

}


ビルド実行結果


sizeof(char)は1バイトです

sizeof(int)は4バイトです

sizeof(float)は4バイトです

sizeof(double)は8バイトです



solarplexuss「わあ


double型は8バイトのデータ容量をもっているんだね」


ソーラー「そうなんです



同様に


キャラアスタリスクchar*型は4バイトのデータ格納容量をもつので


sizeof(char*)は4


をあらわします


イントアスタリスクint*型は4バイトのデータ格納容量をもつので


sizeof(int*)は4


をあらわします


つまり


sizeof(char*)

sizeof(int*)

単なる数値データ4を表しているんです」


solarplexuss「ええ?ど~いうことぉ?


なんで


キャラアスタリスクchar*型

イントアスタリスクint*型


も4バイトのデータ格納容量をもっているの


わっかりませ~ん」


ソーラー「


char*型のポインタ変数宣言


char* p;


によって生成されるポインタ変数pには


char型の変数宣言


char a;


により生成される


char型の変数aのアドレス&aを代入することができます


char* p=&a;


という具合にです


このとき


&aは


例えば

013A8010


のようなアドレスをもちます


もちろん


char* p=&a;


を実行すれば


このaのアドレス013A8010



char*型のポインタ変数pに格納されることになります


じつは


char型の変数の


アドレス013A8010は


メモリに


char*型の形式で格納されているんです


int型の形式で整数値データがメモリに格納されるときは


4バイトのメモリ領域にわたって整数値データは格納されました


char*型の形式でchar型の変数のアドレスが格納されるときも


4バイトのメモリ領域にわたってchar型の変数のアドレスは格納されることになります


アドレス013A8010は16進数で表されていますが


2進数で表すと


0000 0001 0011 1001 1000 0000 0001 0000


で表されることになります


____________________________


アドレス013A8010は16進数で表されていますが


2進数で表すと


0000 0001 0011 1001 1000 0000 0001 0000


になっています


よく観察してみると


実はこのとき



アドレス013A8010


16進数

0

1

3

A

8

0

1

0

2進数

0000

0001

0011

1001

1000

0000

0001

0000


に対応しています


つまり


16進数0=2進数0000     

16進数1=2進数0001  

16進数3=2進数0011  

16進数A=2進数1001  

16進数8=2進数1000 

16進数0=2進数0000  

16進数1=2進数0001  

16進数0=2進数0000  


となっています(*´▽`*)」


____________________________


この32個の


0と1のあつまり

0000 0001 0011 1001 1000 0000 0001 0000

そのまま


char*型の形式で32ビットのメモリのお部屋に格納されることになります


つまり


アドレス013A8010



32ビット=4バイトのデータ量を持つというわけです



同様に



int*型のポインタ変数宣言


int* p;


によって生成されるポインタ変数pには


int型の変数宣言


int a;


により生成される


int型の変数aのアドレス&aを代入することができます


int* p=&a;


という具合にです


このとき


&aは


例えば

00B68010


のようなアドレスをもちます


もちろん


int* p=&a;


を実行すれば


このaのアドレス00B68010



int*型のポインタ変数pに格納されることになります


実は


int型の変数aの


アドレス00B68010は


メモリに


int*型の形式で格納されているんです



int*型のポインタ変数pに


int型の形式で整数値データがメモリに格納されるときは


4バイトのメモリ領域にわたって整数値データは格納されました


int*型の形式でint型の変数のアドレスが格納されるときも


4バイトのメモリ領域にわたってint型の変数のアドレスは格納されることになります


アドレス00B68010は16進数で表されていますが


2進数で表すと


0000 0000 1011 0110 1000 0000 0001 0000


で表されることになります


____________________________


実はこのとき



アドレス00B68010


16進数

0

0

B

6

8

0

1

0

2進数

0000

0000

1011

0110

1000

0000

0001

0000

に対応しています


つまり


16進数0=2進数0000     

16進数0=2進数0000  

16進数B=2進数1011  

16進数6=2進数0110  

16進数8=2進数1000 

16進数0=2進数0000  

16進数1=2進数0001  

16進数0=2進数0000  


となっています(*´▽`*)」


____________________________


この32個の


0と1のあつまり

0000 0000 1011 0110 1000 0000 0001 0000

そのまま


int*型の形式で32ビットのメモリのお部屋に格納されることになります


つまり


アドレス00B68010



32ビット=4バイトのデータ量を持つというわけです


solarplexuss「じゃあ


sizeof(char*)が数値データ4を表すのなら


(sizeof(char*) * 100)は数値データ400をあらわすので



p = (char *)malloc(sizeof(char*) * 100);



p = (char *)malloc(400);


であらわされるってこと?」


ソーラー「そうなんです



早速

そのことを示すプログラムを実行してみようかな


そのプログラムは次の2つです

👇

🍋1つ目🍋

p = (char *)malloc(sizeof(char*) * 100);を実行した場合



#include <stdio.h>

#include <stdlib.h>//🌞malloc関数を使用するときはヘッダファイル<stdlib.h>をインクルードしてください


int main(void) {


char* p;


p = (char *)malloc(sizeof(char*) * 100);//👈ここです



if (p == NULL) {

printf("メモリは確保されませんでした。");

}


else {

printf("メモリは確保されました。");

printf("確保したメモリの先頭のメモリのアドレスは %pです。\n", p);

}


printf("確保されたメモリは%dバイトです\n", sizeof(char*) * 100);


free(p);


return 0;

}


ビルド実行結果


メモリは確保されました。確保したメモリの先頭のメモリのアドレスは 007D9010です。

確保されたメモリは400バイトです




🍋2つ目🍋

p = (char *)malloc(400);を実行した場合


👇

#include <stdio.h>

#include <stdlib.h>//🌞malloc関数を使用するときはヘッダファイル<stdlib.h>をインクルードしてください


int main(void) {


char* p;


p = (char *)malloc(400);//👈sizeof(char*)*100を400と記述しました



if (p == NULL) {

printf("メモリは確保されませんでした。");

}


else {

printf("メモリは確保されました。");

printf("確保したメモリの先頭のメモリのアドレスは %pです。\n", p);

}


printf("確保されたメモリは%dバイトです\n", sizeof(char*) * 100);


free(p);


return 0;

}


ビルド実行結果


メモリは確保されました。確保したメモリの先頭のメモリのアドレスは 01089010です。

確保されたメモリは400バイトです


solarplexuss「なるほど


p = (char *)malloc(sizeof(char*) * 100);



p = (char *)malloc(400);


が実行されることに等しくて


ともに


400バイト分のメモリが確保されるんだね」


  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る