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";


を実行しようとすると


警告文が表示される設定になっています









       


           

                 ちゃんちゃん








































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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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