データ構造とアルゴリズム 第10回 mallocとfree 静岡大学工学部 安藤 和敏 2011.06.17
目次 変数とメモリ (復習) 配列の宣言とメモリ メモリの動的割り当て(malloc)と開放(free) プログラム例:malloc1.c (int型配列) プログラム例:malloc2.c (struct COMPLEX型) 実習
目次 変数とメモリ (復習) 配列の宣言とメモリ メモリの動的割り当て(malloc)と開放(free) プログラム例:malloc1.c (int型配列) プログラム例:malloc2.c (struct COMPLEX型) 実習
コンピュータのメモリのイメージ アドレス 内容 175 1 2 安藤 3 4 浜松 5 6 2004 7 ... ...
変数とメモリ ... ... アドレス 内容 int x; 175 と宣言することによって、xという名前が付けられた4バイト分のメモリ領域が確保される。 1 2 安藤 3 4 浜松 5:x: 6 2004 7 確保されるバイト数はその変数の型に依存する。p.18の表2.3を見よ。 以降は、この確保されたメモリ領域の内容をx と言う名前で参照できるようになる。 ... ...
ポインタとメモリ(教科書p.143-144) int x; int *p=&x; ポインタ変数 pの内容=7 アドレス 内容 175 1:p: 7 2 安藤 3 4 浜松 xの宣言によって確保されたメモリ領域 5 6 2004 7:x:
前ページのような状況を図示するために、このような矢線を用いて表現する。 ポインタとメモリの関係の図示 int x; int *p=&x; 前ページのような状況を図示するために、このような矢線を用いて表現する。 アドレス 内容 p: x:
目次 変数とメモリ (復習) 配列の宣言とメモリ メモリの動的割り当て(malloc)と開放(free) プログラム例:malloc1.c (int型配列) プログラム例:malloc2.c (struct COMPLEX型) 実習
配列の宣言とメモリ ・・・ int array[100]; 配列を、例えばこのように宣言すると、メモリ上に,array[0], array[1], …, array[99] という名前の付いた連続したメモリ領域がプログラムを実行した直後に確保される.この記憶場所には,int型のデータが記憶される. したがって、この宣言によって、100×4=400バイトのメモリがプログラムによって確保される。 実際に使わないメモリ領域をを無駄に確保するかも知れないし、
配列の宣言とメモリ(問題点) ・・・ int array[100]; ちょうど100個の整数のデータを格納することが事前に分かっていれば問題ない。 しかし、実行した後でないと何個のデータを格納しなければならないか分からないということが、良くある。 メモリ領域の過不足が生じる可能性がある。 特に携帯電話のように十分大きなメモリ領域が搭載されていないデバイス上で動くプログラムにおいては、メモリを効率的に使用しなければならない。
目次 変数とメモリ (復習) 配列の宣言とメモリ メモリの動的割り当て(malloc)と開放(free) プログラム例:malloc1.c (int型配列) プログラム例:malloc2.c (struct COMPLEX型) 実習
メモリの動的割り当て 前ページで述べた問題はメモリの動的割り当てという仕組みによって解決できる。 すなわち、データの個数がプログラムの実行前に分かっていなくても、プログラムの実行中にメモリを適切に確保できる。 C言語では、このメモリの動的割り当てを実現するために、mallocとfreeという関数が用意されている。 これらの関数は、ヘッダファイル stdlib.h の中で定義されている。
void *malloc (int size); 確保に成功すれば、確保したメモリの先頭のアドレス(番地)を返す。失敗した場合はNULLを返す。 確保するメモリのバイト数 void * は任意の型を持つ変数へのポインタという意味。実際に使うときには、キャスト演算子(p.22)によって、適当なポインタに変換する必要がある。
malloc の例(int 型のメモリ領域) int *p; p = (int *)malloc(sizeof(int)); 番地 メモリの内容 ポインタ変数 pのためのメモリ領域が確保される。 1 :p: 2 3 4 5 6 7
malloc の例(int 型のメモリ領域) int *p; p = (int *)malloc(sizeof(int)); (int *)malloc(sizeof(int)) そのアドレスは、適切な型に変換(キャスト)されなければならない。 番地 メモリの内容 1:p: mallocによって確保されたメモリ領域。sizeof(int)バイト=4バイト。mallocはこのメモリのアドレスを返す。 2 3 4 5 6 7
malloc の例(int 型のメモリ領域) int *p; p = (int *)malloc(sizeof(int)); p = ポインタ変数 p にmallocによって確保されたメモリのアドレス(5)が代入される。 番地 メモリの内容 1:p: 2 3 これ以降は、ここの内容は p を介して参照できる。例えば、*p=100とか。 4 5 6 7
free int free (void* p); 開放したいメモリ領域の先頭アドレス
目次 変数とメモリ (復習) 配列の宣言とメモリ メモリの動的割り当て(malloc)と開放(free) プログラム例:malloc1.c (int型配列) プログラム例:malloc2.c (struct COMPLEX型) 実習
配列の要素数をプログラムの実行後に決めることができる。 プログラム例 (malloc1.c) /* プログラム 10.5 配列の動的な割り当て */ #include <stdio.h> #include <stdlib.h> main(){ int i,n,*array; printf("N= "); scanf("%d",&n); if ((array=(int *)malloc(n*sizeof(int))) ==NULL) { fprintf(stderr,"malloc failed.\n"); exit(1); } 配列の要素数をプログラムの実行後に決めることができる。
mallocによって確保されたメモリ領域(n×4バイト) int *array; array=(int *)malloc(n*sizeof(int)); とすれば、配列 array の要素数をプログラムの実行中に決めることができる.だから、必要十分なメモリの確保が可能になる。 array: array[0]: array[1]: array[2]: ・・・ mallocによって確保されたメモリ領域(n×4バイト) ・・・ array[n-1]:
配列の要素数をプログラムの実行後に決めることができる。 プログラム例 (malloc1.c) (続き) for(i=0;i<n;i++) { array[i]=i; printf("%d ", array[i]); } putchar('\n'); free(array); 配列の要素数をプログラムの実行後に決めることができる。
目次 変数とメモリ (復習) 配列の宣言とメモリ メモリの動的割り当て(malloc)と開放(free) プログラム例:malloc1.c (int型配列) プログラム例:malloc2.c (struct COMPLEX型) 実習
プログラム例 (malloc2.c) #include <stdio.h> #include <stdlib.h> #define PrintComplex(x) ...(省略) struct COMPLEX {double real; double img;} ; main(){ struct COMPLEX *a; a = (struct COMPLEX *) malloc(sizeof(struct COMPLEX)); a->real = 10; a->img =3; PrintComplex(*a); putchar('\n'); free(a); }
malloc の例(struct COMPLEX型のメモリ領域) struct COMPLEX *a; a = (struct COMPLEX *) malloc(sizeof(struct COMPLEX)); メモリの内容 ポインタ変数 a のためのメモリ領域が確保される。 a:
malloc の例(struct COMPLEX型のメモリ領域) そのアドレスは、適切な型に変換(キャスト)されなければならない。 struct COMPLEX *a; a = (struct COMPLEX *) malloc(sizeof(struct COMPLEX)); (struct COMPLEX *) malloc(sizeof(struct COMPLEX)) メモリの内容 mallocによって確保されたメモリ領域。sizeof(struct COMPLEX)バイト=16バイト。mallocはこのメモリのアドレスを返す。 a: (real) (img)
malloc の例(struct COMPLEX型のメモリ領域) struct COMPLEX *a; a = (struct COMPLEX *) malloc(sizeof(struct COMPLEX)); a = メモリの内容 ポインタ変数 a にmallocによって確保されたメモリのアドレスが代入される。 a: それ以降は、ここの内容はポインタ a を介して参照できる。 a->real, a->img で。 (real) (img)
プログラム例 (malloc2.c) #include <stdio.h> #include <stdlib.h> #define PrintComplex(x) ...(省略) struct COMPLEX {double real; double img;} ; main(){ struct COMPLEX *a; a = (struct COMPLEX *) malloc(sizeof(struct COMPLEX)); a->real = 10; a->img =3; PrintComplex(*a); putchar('\n'); free(a); }
目次 変数とメモリ (復習) 配列の宣言とメモリ メモリの動的割り当て(malloc)と開放(free) プログラム例:malloc1.c (int型配列) プログラム例:malloc2.c (struct COMPLEX型) 実習