ポインタ配列、配列ポインタ、2 D配列動的割り当てメモリ

11101 ワード

1.2 D配列の動的割当てと解放
1.既知の2 D
char (*a)[N];//       
a = (char (*)[N])malloc(sizeof(char *) * m);
printf("%d
"
, sizeof(a));//4, printf("%d
"
, sizeof(a[0]));//N, free(a);

2.既知の次元
char* a[M];//     
int i;
for(i=0; ichar *)malloc(sizeof(char) * n);
printf("%d
"
, sizeof(a));//4*M, printf("%d
"
, sizeof(a[0]));//4, for(i=0; ifree(a[i]);

3.既知の第1次元で、メモリを一度に割り当てる(メモリの連続性を保証する)
char* a[M];//     
int i;
a[0] = (char *)malloc(sizeof(char) * M * n);
for(i=1; i1] + n;
printf("%d
"
, sizeof(a));//4*M, printf("%d
"
, sizeof(a[0]));//4, free(a[0]);

4.両方の次元が不明
char **a;
int i;
a = (char **)malloc(sizeof(char *) * m);//      
for(i=0; i char *)malloc(sizeof(char) * n);//            
}
printf("%d
"
, sizeof(a));//4, printf("%d
"
, sizeof(a[0]));//4, for(i=0; ifree(a[i]); } free(a);

5.両方の次元が不明で、一度にメモリを割り当てます(メモリの連続性を保証します)
char **a;
int i;
a = (char **)malloc(sizeof(char *) * m);//      
a[0] = (char *)malloc(sizeof(char) * m * n);//         
for(i=1; i1] + n;
}
printf("%d
"
, sizeof(a));//4, printf("%d
"
, sizeof(a[0]));//4, free(a[0]); free(a);

2.C++動的割当て2 D配列
1.既知の2 D
char (*a)[N];//       
a = new char[m][N];
printf("%d
"
, sizeof(a));//4, printf("%d
"
, sizeof(a[0]));//N, delete[] a;

2.既知の次元
char* a[M];//     
for(int i=0; inew char[n];
printf("%d
"
, sizeof(a));//4*M, printf("%d
"
, sizeof(a[0]));//4, for(i=0; idelete[] a[i];

3.既知の第1次元で、メモリを一度に割り当てる(メモリの連続性を保証する)
char* a[M];//     
a[0] = new char[M*n];
for(int i=1; i1] + n;
printf("%d
"
, sizeof(a));//4*M, printf("%d
"
, sizeof(a[0]));//4, delete[] a[0];

4.両方の次元が不明
char **a;
a = new char* [m];//      
for(int i=0; inew char[n];//            
}
printf("%d
"
, sizeof(a));//4, printf("%d
"
, sizeof(a[0]));//4, for(i=0; idelete[] a[i]; delete[] a;

5.両方の次元が不明で、一度にメモリを割り当てます(メモリの連続性を保証します)
char **a;
a = new char* [m];
a[0] = new char[m * n];//         
for(int i=1; i1] + n;//            
}
printf("%d
"
, sizeof(a));//4, printf("%d
"
, sizeof(a[0]));//4, delete[] a[0]; delete[] a;

newとdeleteはペアで使用することに注意してください.つまり、どれだけのnewがどれだけのdeleteがあるか、メモリの漏洩を避けることができます.
3.静的2次元配列を関数パラメータとして渡す
上記のいくつかの方法で2次元配列を動的に割り当てると,対応するデータ型を関数パラメータとして用いることができる.ここでは、静的2 D配列が関数パラメータとして渡されることについて説明します.すなわち、次のように呼び出されます.
   int a[2][3];
   func(a);

C言語では静的2次元配列をパラメータとして渡すのは面倒で、一般的には2次元の長さを指定する必要がありますが、2次元の長さが指定されていない場合は、まず1次元ポインタとして渡すしかありません.その後、2次元配列の線形記憶特性を利用して、関数内で指定された要素へのアクセスに変換します.まず、パラメータ伝達の正確性を検証するために、テストコードを作成します.
1.2次元の長さを指定
void func(int a[][N])
{
    printf("%d
"
, a[1][2]); }

2.2次元の長さを指定しない
void func(int* a)
{
    printf("%d
"
, a[1 * N + 2]);// }

注意:この関数を使用する場合は、2 D配列の先頭アドレスを1 Dポインタ、すなわちfunc((int*)a);に強制的に変換する必要があります.