int**型のポインタ変数を用いてmalloc関数を2段階用いることにより2次元配列的にメモリを確保することができます それらのメモリを2段階free関数を用いて解放してみます

ソーラー「🌞どう?🌞  🌞どう?🌞


char**型のポインタ変数を用いてmalloc関数を2段階用いることにより2次元配列的に動的にメモリを確保することができ

動的に確保されたメモリを2段階,free関数を用いて解放することができました


メモリの解放の方法が2段階で


面白い仕組みだったね



今度は


int**型のポインタ変数を用いてmalloc関数を2段階用いることにより2次元配列的に動的にメモリを確保し

動的に確保されたメモリを2段階,free関数を用いて解放してみたいと思います



int** a;


a = (int**)malloc(sizeof(int*)*2);


を実行して動的にメモリを確保したとき


確保したメモリの先頭のアドレスが


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


そして


free(a);


を実行すると


動的に確保されたメモリを解放することができました


ところで


int** a;


a = (int**)malloc(sizeof(int*)*2);


が実行されると


int**型のポインタ変数aには


        💖アドレスが代入されるので💖


aに[]演算子を用いた


a[0]

a[1]


データを代入することができるようになります


そのデータとはアドレスであり


生成される

a[0]

a[1]

int*型のポインタ変数なのです



(このことは

👇

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


        アドレスが代入したとき


int*型のポインタ変数aに[]演算子を用いた


a[0]

a[1]

整数値データを代入することができるようになります


このとき

a[0]

a[1]



int型の変数を表しています


👆


の関係と一緒です)



a[0]

a[1]

int*型のポインタ変数なので



さらに


a[0] = (int*)malloc(sizeof(int)*3);

a[1] = (int*)malloc(sizeof(int)*3);


を実行して


int*型のポインタ変数


a[0]

a[1]

を用いて動的にメモリを確保することができましたね



つまり


a[0] = (int*)malloc(sizeof(int)*3);


a[1] = (int*)malloc(sizeof(int)*3);


を実行することにより


動的にメモリが確保されることになるのですが


このとき


a = (int**)malloc(sizeof(int*)*2);

a[0] = (int*)malloc(sizeof(int)*3);

a[1] = (int*)malloc(sizeof(int)*3);

の実行により


動的にメモリが確保されているわけです


a = (int**)malloc(sizeof(int*)*2);


の実行によりメモリが動的に8バイト分確保され


a[0] = (int*)malloc(sizeof(int)*3);

a[1] = (int*)malloc(sizeof(int)*3);

の実行により

それぞれ

メモリが


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


sizeof(int)*3=4×3=12



12バイト分確保されることになります



このとき


a[0]に[]演算子を用いた


a[0][0]

a[0][1]

a[0][2]


a[1]に[]演算子を用いた


a[1][0]

a[1][1]

a[1][2]

int型の配列変数であり


int型の配列変数

a[0][0]

a[0][1]

a[0][2]


a[1][0]

a[1][1]

a[1][2]

には

整数値データを格納することができます


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

👇

#include <stdio.h>

#include <stdlib.h> /* malloc関数を用いるにはヘッダファイル<stdlib.h>をインクルードします*/


int main(void) {


int** a;


a = (int**)malloc(sizeof(int*) * 2);

//🌞malloc関数を用いてメモリを8バイト分確保しています🌞


a[0] = (int*)malloc(sizeof(int) * 3);

//🌞malloc関数を用いてメモリを12バイト分確保しています🌞

a[1] = (int*)malloc(sizeof(int) * 3);

//🌞関数を用いてメモリを12バイト分確保しています🌞


a[0][0] = 1;

a[0][1] = 2;

a[0][2] = 3;


a[1][0] = 4;

a[1][1] = 5;

a[1][2] = 6;


printf("%d\n", a[0][0]);

printf("%d\n", a[0][1]);

printf("%d\n", a[0][2]);

printf("%d\n", a[1][0]);

printf("%d\n", a[1][1]);

printf("%d\n", a[1][2]);


return 0;

}


ビルド実行結果


1

2

3

4

5

6



ソーラー「


a = (int**)malloc(sizeof(int*)*2);


の実行により動的に確保された8バイト分のメモリには


ポインタ変数

a[0]

a[1]

のアドレスが格納されています


a[0] = (int*)malloc(sizeof(int)*3);


の実行により動的に確保された12バイト分のメモリには


a[0]に[]演算子を用いた


a[0][0]=1;

a[0][1]=2;

a[0][2]=3;


の実行により


数値データ

1

2

3


が格納されています


a[1] = (int*)malloc(sizeof(int)*3);


の実行により動的に確保された3バイト分のメモリには


a[1]に[]演算子を用いた


a[1][0]=4;

a[1][1]=5;

a[1][2]=6;


の実行により


数値データ

4

5

6


が格納されています


さて


動的に確保されたメモリを解放するには


free関数の引数に


それらの動的に確保されたメモリの先頭のアドレスを格納しているポインタ変数を用いる必要があります


a = (int**)malloc(sizeof(int*)*2);


の実行により動的に確保された8バイト分のメモリの先頭のアドレスを格納しているポインタ変数はaであり


a[0] = (int*)malloc(sizeof(int)*3);


の実行により動的に確保された12バイト分のメモリの先頭のアドレスを格納しているポインタ変数はa[0]であり


a[0] = (int*)malloc(sizeof(int)*3);


の実行により動的に確保された12バイト分のメモリの先頭のアドレスを格納しているポインタ変数はa[1]ですね


ですので


a = (int**)malloc(sizeof(int*)*2);


の実行により動的に確保された8バイト分のメモリを解放するには


free(a);


を実行する必要があり


a[0] = (int*)malloc(sizeof(int)*3);


の実行により動的に確保された12バイト分のメモリを解放するには


free(a[0]);


を実行する必要があり


a[1] = (int*)malloc(sizeof(int)*3);


の実行により動的に確保された12バイト分のメモリを解放するには


free(a[1]);


を実行する必要があります


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

👇

#include <stdio.h>

#include <stdlib.h> /* malloc関数を用いるにはヘッダファイル<stdlib.h>をインクルードします*/


int main(void) {


int** a;


a = (int**)malloc(sizeof(int*) * 2);

//🌞malloc関数を用いてメモリを8バイト分確保しています🌞


a[0] = (int*)malloc(sizeof(int) * 3);

//🌞malloc関数を用いてメモリを12バイト分確保しています🌞

a[1] = (int*)malloc(sizeof(int) * 3);

//🌞関数を用いてメモリを12バイト分確保しています🌞


a[0][0] = 1;

a[0][1] = 2;

a[0][2] = 3;


a[1][0] = 4;

a[1][1] = 5;

a[1][2] = 6;


printf("%d\n", a[0][0]);

printf("%d\n", a[0][1]);

printf("%d\n", a[0][2]);

printf("%d\n", a[1][0]);

printf("%d\n", a[1][1]);

printf("%d\n", a[1][2]);


free(a);

free(a[0]);

free(a[1]);


return 0;

}


ビルド実行結果

1

2

3

4

5

6


ソーラー「どう?


このプログラムでは


free(a);

free(a[0]);

free(a[1]);


の実行により


a = (int**)malloc(sizeof(int*)*2);


の実行により動的に確保された8バイト分のメモリ


a[0] = (int*)malloc(sizeof(int)*3);


の実行により動的に確保された12バイト分のメモリ


a[1] = (int*)malloc(sizeof(int)*3);


の実行により動的に確保された12バイト分のメモリ


が解放されています


このときのポイントは


            😸free(a);😸

の実行により


      a = (int**)malloc(sizeof(int*)*2);


の実行により動的に確保された8バイト分のメモリを解放したとしても


a[0] = (int*)malloc(sizeof(int)*3);


の実行により動的に確保された12バイト分のメモリ


a[1] = (int*)malloc(sizeof(int)*3);


の実行により動的に確保された12バイト分のメモリ


は解放されないということです


            同様に



           😸free(a[0]);😸

           😸free(a[1]);😸


の実行により


a[0] = (int*)malloc(sizeof(int)*3);


の実行により動的に確保された12バイト分のメモリ


a[1] = (int*)malloc(sizeof(int)*3);


の実行により動的に確保された12バイト分のメモリ

を解放したとしても



      a = (int**)malloc(sizeof(int*)*2);


  の実行により動的に確保された8バイト分のメモリを


解放することはできません



動的にメモリを確保して


動的に確保したメモリを解放したと思っても


解放されないメモリが残っていることになるというわけなんだ


注意してね


だから


何回も

動的にメモリを確保して


動的に確保したメモリを解放するということを繰り返して


動的に確保したメモリを解放したと思っていても


どんどん


コンピュータがアクセスして使用することのできないメモリが


増えていくことになります


注意してね」


アレサ「おみごとですの」


solarplexuss「やった! ついに



int**型のポインタ変数aを用いて2次元配列的にメモリに確保し


free(a);

free(a[0]);

free(a[1]);


を実行して


それらのメモリを解放することができるようになった」


ありがとう😊


アレサ💖


ソーラー💖」







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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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