2012年12月24日月曜日

動的な配列の確保


C言語の配列では要素数を変更できません。
なのでポインタを使い、動的な配列の確保を行います。

使う関数は、mallocとreallocでstdlib.hをインクルードする必要があります。

はじめはmallocの使い方。
mallocの戻り値はvoid型ポインタなので、キャストしてあげます。
引数は、確保したいメモリのバイト数なので、sizeof(型)*要素数を渡してください。
なので、今回は(char**)malloc(sizeof(char*)*要素数)としてます。
mallocの注意点としては、メモリを確保できなかった時はNULLを返すところです。
なのでif(pp==NULL)とかいれて対処するとよいでしょう。
今回は特にNULLの時の処理は入れていません。
mallocがNULLを返すときはOSがメモリを渡してくれないときなので、プログラムを終了させる処理でも入れとけばいいと思います。
それと、最後にfree()を使い確保したメモリを開放しましょう。
#include <stdio.h>
#include <stdlib.h>

int main() {
 char **pp; //配列
 const int ele = 3; //要素数
 int i;
 //メモリを確保
 pp = (char**) malloc(sizeof(char*) * ele);

 for (i = 0; i < ele; i++) {
  //メモリを確保
  pp[i] = (char*) malloc(sizeof(char) * 15);
  sprintf(pp[i], "Hello - %d", i); //テストのために入れておく
 }
 //中身を確認
 printf("printf test\n");
 for (i = 0; i < ele; i++) {
  fprintf(stdout, "%s\n", pp[i]);
  free(pp[i]); //忘れないで
 }
 free(pp); //忘れないで
 return 0;
}
次にreallocを使い動的な配列をつくります。
reallocは割り当てたメモリを再度確保しなすのでその時にサイズを変えます。
reallocもメモリが確保できなかった場合にNULLを返すのでそれの処理を入れておくとよいでしょう。
#include <stdio.h>
#include <stdlib.h>
int main() {
 char **pp; //配列
 const int ele = 3; //要素数
 int i;
 //メモリを確保
 pp = (char**) malloc(sizeof(char*) * ele);

 for (i = 0; i < ele; i++) {
  //メモリを確保
  pp[i] = (char*) malloc(sizeof(char) * 15);
  sprintf(pp[i], "Hello - %d", i); //テストのために入れておく
 }

 //中身を確認
 printf("printf test\n");
 for (i = 0; i < ele; i++) {
  fprintf(stdout, "%s\n", pp[i]);
 }

 printf("メモリ再確保\n");
 //2倍のメモリを再確保
 pp = (char**) realloc(pp, sizeof(char*) * ele * 2);
 for (i = 0; i < ele; i++) {
  //メモリを確保
  pp[i + ele] = (char*) malloc(sizeof(char) * 15);
  sprintf(pp[i + ele], "Hello - %d", i + ele); //テストのために入れておく
 }
 printf("printf test\n");
 for (i = 0; i < ele * 2; i++) {
  fprintf(stdout, "%s\n", pp[i]);
  free(pp[i]);
 }
 free(pp); //忘れないで
 return 0;
}

最後に、ポインタって配列みたいな書き方ができるよ。
*(pp+i)とpp[i]は同じです。

0 件のコメント:

コメントを投稿