malloc関数によって確保されたメモリにデータを入力しfree関数によってメモリ開放を行ってみます その1

ソーラー「今のプログラムでは→


#include <stdio.h>

#include <stdlib.h>


int main(void) {


char *p;


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


if (p == NULL) {

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

}


else {

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

printf("そのメモリのアドレスは %pです。\n", p);

}



printf("%p\n", &p[0]);//ここでp[0]のアドレスをもとめています

printf("%p\n", &p[1]);//ここでp[1]のアドレスをもとめています

printf("%p\n", &p[2]);//ここでp[2]のアドレスをもとめています

printf("%p\n", &p[3]);//ここでp[3]のアドレスをもとめています

printf("%p\n", &p[4]);//ここでp[4]のアドレスをもとめています


free(p);


return 0;

}


コンパイル結果


メモリは確保されました。

そのメモリのアドレスは00E64B40です。

00E64B40

00E64B41

00E64B42

00E64B43

00E64B44


ソーラー「→malloc関数を使って


00E64B40

00E64B41

00E64B42

00E64B43

00E64B44

のアドレスをもつメモリを


コンピュータが利用できないよう確保し


free関数を使って


コンピュータが利用できるよう解放しました。」


ソーラー「しかし


malloc関数をつかって


メモリを確保して


free関数で


メモリを解放しただけでは


malloc関数が何のためにあるのかよく分からないよね


一体このmalloc関数はどのようなときにプログラムで用いられるのか


気になるんじゃないかな


そこで今度は


malloc関数を用いるとどのような点が便利なのかプログラムを


構成して確かめてみよ~うじゃないか~」



アレサ「はいっ😊先程のプログラムをご用意いたします。

👇

#include <stdio.h>

#include <stdlib.h>


int main(void) {


char *p;


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


if (p == NULL) {

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

}


else {

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

printf("そのメモリのアドレスは %pです。\n", p);

}



printf("%p\n", &p[0]);//ここでp[0]のアドレスをもとめています

printf("%p\n", &p[1]);//ここでp[1]のアドレスをもとめています

printf("%p\n", &p[2]);//ここでp[2]のアドレスをもとめています

printf("%p\n", &p[3]);//ここでp[3]のアドレスをもとめています

printf("%p\n", &p[4]);//ここでp[4]のアドレスをもとめています


free(p);


return 0;

}


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


00E64B40

00E64B41

00E64B42

00E64B43

00E64B44

のアドレスをもつメモリが


malloc関数によって確保されましたが


00E64B40

00E64B41

00E64B42

00E64B43

00E64B44

のアドレスをもつメモリには


ポインタ変数宣言


char *p;


によって作製された

char型の配列変数

p[0]

p[1]

p[2]

p[3]

p[4]


を使ってアクセスすることができます


つまり


char型の配列変数

p[0]

p[1]

p[2]

p[3]

p[4]

に文字データを格納すると


00E64B40

00E64B41

00E64B42

00E64B43

00E64B44

のアドレス番号をもつメモリに


文字データを格納することができるというわけです。


そこで

💖💖💖💖💖💖

char型の配列変数

p[0]

p[1]

p[2]

p[3]

p[4]

をつかって

00E64B40

00E64B41

00E64B42

00E64B43

00E64B44

のアドレス番号をもつメモリに


文字データを格納してから


free関数によりメモリ解放を行ってみようと思うんだ

💖💖💖💖💖💖


ソーラー「では


そのプログラムをお願いしようかな」


アレサ「はいっ😊


とても楽しみですの。


そのプログラムはこちらになります。



#include <stdio.h>

#include <stdlib.h>


int main(void) {


char *p;


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


if (p == NULL) {

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

}


else {

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

printf("そのメモリのアドレスは %pです。\n", p);

}



printf("%p\n", &p[0]);//ここでp[0]のアドレスをもとめています

printf("%p\n", &p[1]);//ここでp[1]のアドレスをもとめています

printf("%p\n", &p[2]);//ここでp[2]のアドレスをもとめています

printf("%p\n", &p[3]);//ここでp[3]のアドレスをもとめています

printf("%p\n", &p[4]);//ここでp[4]のアドレスをもとめています



p[0]='n';

p[1]='e';

p[2]='k';

p[3]='o';

p[4]='\0';/*ここにナル文字を格納することでポインタ変数pを使って

文字列データ"neko"をメモリに格納したことになります*/


printf("%c\n", p[0]);

printf("%c\n", p[1]);

printf("%c\n", p[2]);

printf("%c\n", p[3]);

printf("%c\n", p[4]);


printf("%s\n", p);

/*ポインタ変数pを使って

文字列データ"neko"をコマンドプロンプト画面に表示します*/


free(p);


return 0;

}


コンパイル結果

メモリは確保されました。

そのメモリのアドレスは010D4B40です。

010D4B40

010D4B41

010D4B42

010D4B43

010D4B44

n

e

k

o

(空白)

neko



(これらのアドレスの値はメモリの使用状況によってことなってきます。)


ソーラー「このプログラムのポイントは


malloc関数によって確保された


010D4B40

010D4B41

010D4B42

010D4B43

010D4B44

のアドレス番号の付いたメモリに


char型の配列変数

p[0]

p[1]

p[2]

p[3]

p[4]

をつかって


文字列データ"neko"



p[0]='n';

p[1]='e';

p[2]='k';

p[3]='o';

p[4]='\0';


と格納したことにあるんだよ


このとき


コンピュータは


010D4B40

010D4B41

010D4B42

010D4B43

010D4B44

のアドレス番号の付いた5バイト分のメモリを


使用することはできません。


もし


free関数を使ってメモリ解放をおこなわなければ


プログラムの実行が終了するまで


010D4B40

010D4B41

010D4B42

010D4B43

010D4B44

のアドレス番号の付いた5バイト分のメモリを


使用することはできません。


ところで


このプログラムでは


コンパイル結果

メモリは確保されました。

そのメモリのアドレスは010D4B40です。

010D4B40

010D4B41

010D4B42

010D4B43

010D4B44

n

e

k

o

(空白)

neko


が表示されれば


010D4B40

010D4B41

010D4B42

010D4B43

010D4B44

のアドレス番号の付いた5バイト分のメモリを


確保しておく必要はないよね。


つまり


printf("%c\n", p[0]);

printf("%c\n", p[1]);

printf("%c\n", p[2]);

printf("%c\n", p[3]);

printf("%c\n", p[4]);


printf("%s\n", p);


が実行されたら


010D4B40

010D4B41

010D4B42

010D4B43

010D4B44

のアドレス番号の付いた5バイト分のメモリを


確保しておく必要はないってわけだ


そこで


printf("%c\n", p[0]);

printf("%c\n", p[1]);

printf("%c\n", p[2]);

printf("%c\n", p[3]);

printf("%c\n", p[4]);


printf("%s\n", p);


が実行されたのち


free(p);


を実行して


ポインタ変数pをメモリから消去し


char型の配列変数

p[0]

p[1]

p[2]

p[3]

p[4]


を消去することにより


char型の配列変数

p[0]

p[1]

p[2]

p[3]

p[4]

がアクセスしている


010D4B40

010D4B41

010D4B42

010D4B43

010D4B44

のアドレス番号の付いたメモリを


解放したってわけなんだ


free(p);


が実行されて


010D4B40

010D4B41

010D4B42

010D4B43

010D4B44

のアドレス番号の付いたメモリが


解放されたなら


コンピュータは


010D4B40

010D4B41

010D4B42

010D4B43

010D4B44

のアドレス番号の付いたメモリを


使用することができることになるんだよ」


アレサ「char *p;


によって作製された

char型の配列変数

p[0]

p[1]

p[2]

p[3]

p[4]


をつかって確保された


010D4B40

010D4B41

010D4B42

010D4B43

010D4B44

のアドレス番号の付いたメモリに文字データを格納できるんですね。


メモリが確保されてコンピュータはそのメモリを使用できないとは言っても

データをそのメモリに格納することはできるんですの。」



ソーラー「今日はここまでにしよっかな」





































































































































































































































































































































ソーラーのお洗濯実況中です



ソーラー「実に清々しいな~


こんなに青空が広がっていると気分がいいね。


天気もいいし僕はお洗濯でもしようかな」



ソーラーさん、大分洗濯物がたまっていたようです



アレサ「ソーラーさん 私もお手伝いしましょうか?」


ソーラー「いや そこまでは・・


君には助けてもらってばかりだからね」


アレサ「いえいえ 遠慮なさらずに」


ソーラー「いやあ とりあえず このかんかん照りのお日様で


乾かしてしまおうと思ったんだ」


アレサ「確かに今日はとてもお日様が眩しいです。」


ソーラー「さあてと この洗濯物をどうしようかな」


アレサ「お任せください」


アレサは洗濯ものを受け取ると水を張った桶にさっとひたす


すると


一瞬で汚れが落ちてしまった


驚きの白さだ


すぐさま


アレサが


洗濯ものを物干し竿に干しにかかる。


ソーラー「アレサ どうなってるんだい


洗濯ものがぴかぴかしてるね すごいな~」


アレサ「ソーラーさん 洗濯物がもう乾いていますの」


ソーラー「は、はやい い、いや 暑すぎるんだ」





ソーラー、アレサ「はい、この驚きの白さ


というわけで お洗濯には





       台所洗剤チャレンジ ジョイ!」





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

作者を応援しよう!

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

応援したユーザー

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