パソコン活用研究シリコンバレー(C、C++、の活用研究)

malloc基本的な使用例

mallocの仕様を学んでも、実際にどのように使うのかぴんとこないと思いますので、簡単な
使用例をあげて説明します。

1行入力すると、mallocでメモリを確保して保存し、入力し終わると(=何も入力せずリターン
キーを押すと)、表示しつつfreeでメモリを解放するプログラム。

# include <stdio.h>
#include <string.h>
#include <stdlib.h>

main(argc, argv)
int argc;
char **argv;
{ char buf[100];
  char **line,s[1][1];
  int i,j,len;
 *line = s[0];
 i=1;
gets(buf);               /@/
len = strlen(buf);           /A/

while( strlen(buf) != 0 ) {
line[i] = malloc(len+1);      /B/ 
if (line[i] == NULL) break;      /C/
strcpy(line[i], buf);            /D/
gets(buf);
i++;}

for (j=1; j<i; j++) {
puts(line[j]);                  /E/
free(line[j]);}                 /F/
}

簡単なプログラムですが、ポイントは以下の通りです。
@ 1行入力します。
A 文字列の長さを変数lenに代入します
B mallocで必要領域を確保しますが、文字列終了の印の'\0'の分としてlen+1だけ確保します
C mallocが領域確保できなかったらbreakでwhileループから飛び出します
D strcpy でbufに一時的に保存した文字列(のポインタ)をline配列にコピーします
E line配列を表示
F freeで確保した領域を解放します

実行例は以下の通り

D:\win95\C>malloc2          
12345
abc
yes
no

12345
abc
yes
no



今度は、やってることは上と同じ(1行入力すると、mallocでメモリを確保して保存し、入力し終わると
(=何も入力せずリターンキーを押すと)、全て表示してから、freeでメモリを解放するプログラム)ですが、
mallocが良く使われる自己参照構造体にしてみました。実用的には、このような使い方が多いと思います。
ここでは、シンプルな構造体なので、上の例に比べて自己参照構造体のメリットはありませんが、複雑
な構造体になれば、こういうツリー構造でのデータ管理が必須になります。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct str{
char *c;
struct str *next;
};

main()
{
struct str dmy;
struct str *start=&dmy;
struct str *wkdata;
struct str *wp;
char buf[100]="";

start=&dmy;
start->next=NULL;
wp=start;

while(1){
printf(":");
gets(buf);
if(strcmp(buf,"")==0) break;

wkdata=(struct str *)malloc(sizeof(struct str)); /* @ */
if (wkdata == NULL) {goto q;}
wkdata->c=malloc(strlen(buf)+1); /*A*/
if (wkdata->c == NULL) {free(wkdata); goto q;}
strcpy(wkdata->c,buf); /* B */
wkdata->next=NULL; /* C */
wp->next=wkdata; /* D */
wp=wkdata; /* E */
}

for(wp=start->next;wp != NULL; wp=wp->next){
puts(wp->c);}

q:
for(wp=start->next;wp != NULL; wp=wp->next){
free(wp);
free(wp->c);
}
}





@構造体strの領域を確保する。
Amallocで必要領域を確保しますが、文字列終了の印の'\0'の分としてlen+1だけ確保します
B一時的bufに一時的に保存した文字列(のポインタ)をwkdata->cにコピーします。
Cwkdata->next をNULLにします。NULLは最後のデータの印とします。
Dwpはwkdataよりひとつ前のstr構造体変数なので、ひとつ前のnextにwkdataを設定し、
  チェーンを作ります。
Ewpの指し示すポインタをwkdataにする。すなわちwpを最新のpersonal構造体を指し示すようにします。

以下、実行例です。

D:\win95\C>malloc_t
:1
:234
:x y z
:end!!
:
1
234
x y z
end!!

D:\win95\C>



TopPage