p = (char *)malloc(sizeof(char)*5);と確保されたメモリにp="neko";と文字列データを格納することはできません
malloc関数を使って確保されたメモリに文字列データを格納するには🌞必ず🌞strcpy関数を使用する必要があります
つづき🐤 🐤 🐤・・・
まずは
malloc関数を用いて動的に確保されたメモリに
文字列データ"neko"
を格納する
以下のプログラムをご覧ください
👇
#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, 5, "neko");
/*strcpy_s関数を用いることによりmalloc関数を使って動的に確保したメモリに文字列データ"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関数を使って動的に確保されたメモリに
文字列データ"neko"を格納するには
p[0]='n';
p[1]='e';
p[2]='k';
p[3]='o';
p[4]='\0';
を実行するより
strcpy_s(p, 5, "neko");
を実行するほうが
簡単だね
p="neko";
を実行したほうが簡単そうに思えるけど
p="neko";
を実行すると警告文が表示されるので注意してくださいね」
アレサ「ソーラーさん
p="neko";
を実行すれば
ポインタ変数pに文字列データ
"neko"
が格納される
つまり
malloc関数を使って確保されたメモリに文字列データ
"neko"
を格納できるのではないですか?」
ソーラー「そこは
とっても間違いやすいところなんだ
まず
p="neko";
を実行すれば
ポインタ変数pに文字列データ
"neko"
が格納されるのではなく
p="neko";
を実行すれば
ポインタ変数pを使って
文字列データ"neko"
を
メモリに格納できるというほうが正しいかな😊」
アレサ「??」
ソーラー「たとえば
p="neko";
を実行すると
ポインタ変数pを使って
文字列データ"neko"
を
メモリに格納できるよね」
アレサ「はい ポインタ変数の基本的な性質ですね」
ソーラー「
p="neko";
を実行した後
p="nyao";
を実行したなら
文字列データ
"neko"
を格納したメモリに
文字列データ
"nyao"
は格納されるのかな?」
アレサ「・・・そうはならないです
p="neko";
を実行した後
p="nyao";
を実行したなら
文字列データ
"neko"
を格納したメモリとは違う別のメモリに
文字列データ
"nyao"
は格納されます
つまり
ポインタ変数pを使って
文字列データを格納するときは
文字列データは
同じメモリに上書きされるのではなく
異なるメモリに格納されていくのですの
それがポインタ変数を使って
メモリに
文字列データを格納するときの基本的な性質でした」
ソーラー「そう!
まさにそこなんだ!」
アレサ「え???」
ソーラー「
p = (char *)malloc(sizeof(char)*5);
によって
動的に確保されたメモリに
文字列データを格納しようとして
p="neko";
を実行すると
p = (char *)malloc(sizeof(char)*5);
によって
動的に確保されたメモリとは
💖別のメモリ💖
に
文字列データは格納されるんだよ」
アレサ「はい・・・」
ソーラー「ちょっとまってよ・・・
別の説明をしてみると・・・
p = (char *)malloc(sizeof(char)*5);
を実行すると
どこかのメモリが5バイト分確保されることになりますが
そのメモリの先頭のアドレスが
ポインタ変数pに格納されることになります
次に
p="neko";
が実行されると
どこかのメモリに文字列データ"neko"は
格納されることになりますが
そのメモリの先頭のアドレスが
ポインタ変数pに格納されることになります
つまり
🌞動的に確保されたメモリに🌞
🌞文字列データ"neko"を格納するという🌞
🌞命令は実行されていないんだよ🌞
」
アレサ「はい!😊ソーラーさん」
ソーラー「そこで
p = (char *)malloc(sizeof(char)*5);
によって
動的に確保されたメモリに文字列データを格納するには
strcpy_s(strcpy)関数を
使うことになります
😊strcpy_s(strcpy)関数の特徴は😊
😊ポインタ変数が格納しているアドレスに😊
😊文字列データを😊
😊格納できるという点なんです😊
strcpy_s(p, 5, "neko");
なら
ポインタ変数pが格納しているアドレスにあてて
文字列データ"neko"を格納することができます
ポインタ変数pが格納しているアドレスは
malloc関数を使って確保されたメモリの(先頭の)アドレスでした
ですので
strcpy_s(p, 5, "neko");
を実行すれば
ポインタ変数pが格納しているアドレスにあてて
つまり
malloc関数を使って確保されたメモリに文字列データ
"neko"
を格納することができるんだね」
アレサ「そうだったのですか ソーラーさん
ついに
そこまで理解されたのですね」
ソーラー「はは😊」
おまけ
それでも
strcpy_s(p, 5, "neko");
を使わずに
p="neko";
を実行すると
malloc関数を使って確保されたメモリとは
別のメモリに文字列データ"neko"は格納されることになります
すると
もう
strcpy_s(p, 5, "neko");
を使って
malloc関数を使って確保されたメモリに
文字列データ"neko"
を格納することはできなくなります
なぜなら
p="neko";
を実行した時点で
ポインタ変数pには
malloc関数を使って確保されたメモリのアドレスではなく
文字列データ"neko"を格納したメモリのアドレスが
格納されることになるからです
ですから
p="neko";
を実行したあと
strcpy_s(p, 50, "neko");
を実行すると
文字列データ"neko"を格納したメモリに
文字列データ"neko"が格納されることになります
strcpy_s関数をポインタ変数pに用いた
strcpy_s(p, 5, "neko");
を使って
malloc関数を使って確保されたメモリに
文字列データ"neko"
を格納することはできなくなるということは
いいかえれば
もう
malloc関数を使って確保されたメモリに
文字列データを格納することができないということになります
すると
動的に確保されたメモリは
誰からもアクセスされることなく
メモリ上に存在することになり
コンピュータが使用できるメモリ量は
その分減るということになります
このような状態を
メモリリークといいます💖
メモリリークが大量に発生すると
コンピュータが使用できるメモリ量が少なくなり
コンピュータがフリーズ(止まってしまう)することになります
そのようなことを避けるために
Visual Studioでは
p = (char *)malloc(sizeof(char)*5);
によって
動的にメモリを確保した後
p="neko";
を実行しようとすると
警告文が表示される設定になっています
ちゃんちゃん
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます