malloc関数を使って確保されたメモリに文字列データを格納するには🌞必ず🌞strcpy関数を使用する必要があります
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関数によって確保されましたが
このことを動的にメモリが確保されたといいます
☆ ☆ ☆ ☆ ☆ ☆ ☆
動的にメモリを確保するということはいつでも
確保されたメモリを解放できるという意味が込められています
確保されたメモリを解放することに関しては詳しくはこれから解説されます
solarplexussより
☆ ☆ ☆ ☆ ☆ ☆ ☆
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に格納されているアドレス
(ポインタ変数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
のアドレス番号の付いたメモリに文字データを格納できるんですね。
メモリが確保されて
コンピュータはそのメモリを使用できないとはいっても
ユーザーはそのメモリにデータを自由に格納することができるんですね」
ソーラー「今日はここまでにしよっかな
とおもったけど
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';
と格納するのは
手間がかかるね。
実は
strcpy_s関数を用いて
strcpy_s(p, 50, "neko");
を実行すれば
簡単に
文字列データ"neko"
を
p[0]='n';
p[1]='e';
p[2]='k';
p[3]='o';
p[4]='\0';
と格納することができます。
その際
ヘッダファイル<string.h>をインクルードしてください
ヘッダファイル<string.h>をインクルードしなければ
strcpy_s関数
を使用することはできません
そのことを示すプログラムはこちらです😊
👇
#include <stdio.h>
#include <stdlib.h>
#include <string.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]のアドレスをもとめています
strcpy_s(p, 50, "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
ソーラー「
p[0]='n';
p[1]='e';
p[2]='k';
p[3]='o';
p[4]='\0';
を実行するより
strcpy_s(p, 50, "neko");
を実行するほうが
簡単だね
p="neko";
を実行したほうが簡単そうに思えるけど
p="neko";
を実行すると警告文が表示されるので注意してくださいね」
アレサ「ソーラーさん
p="neko";
を実行すれば
ポインタ変数pに文字列データ
"neko"
が格納されるのではないですか?」
ソーラー「そこはとっても間違いやすいところなんだ
p="neko";
を実行すれば
ポインタ変数pに文字列データ
"neko"
が格納されるのではなく
p="neko";
を実行すれば
ポインタ変数pを使って
文字列データ"neko"
を
メモリに格納できるというほうが正しいかな😊」
アレサ「??」
ソーラーのお洗濯実況中です
ソーラー「実に清々しいな~
こんなに青空が広がっていると気分がいいね。
天気もいいし僕はお洗濯でもしようかな」
ソーラーさん、大分洗濯物がたまっていたようです
アレサ「ソーラーさん 私もお手伝いしましょうか?」
ソーラー「いや そこまでは・・
君には助けてもらってばかりだからね」
アレサ「いえいえ 遠慮なさらずに」
ソーラー「いやあ とりあえず このかんかん照りのお日様で
乾かしてしまおうと思ったんだ」
アレサ「確かに今日はとてもお日様が眩しいです。」
ソーラー「さあてと この洗濯物をどうしようかな」
アレサ「お任せください」
アレサは洗濯ものを受け取ると水を張った桶にさっとひたす
すると
一瞬で汚れが落ちてしまった
驚きの白さだ
すぐさま
アレサが
洗濯ものを物干し竿に干しにかかる。
ソーラー「アレサ どうなってるんだい
洗濯ものがぴかぴかしてるね すごいな~」
アレサ「ソーラーさん 洗濯物がもう乾いていますの」
ソーラー「は、はやい い、いや 暑すぎるんだ」
ソーラー、アレサ「はい、この驚きの白さ
というわけで お洗濯には
台所洗剤チャレンジ ジョイ!」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます