ポインタ配列、配列ポインタ、2 D配列動的割り当てメモリ
1.2 D配列の動的割当てと解放
1.既知の2 D
2.既知の次元
3.既知の第1次元で、メモリを一度に割り当てる(メモリの連続性を保証する)
4.両方の次元が不明
5.両方の次元が不明で、一度にメモリを割り当てます(メモリの連続性を保証します)
2.C++動的割当て2 D配列
1.既知の2 D
2.既知の次元
3.既知の第1次元で、メモリを一度に割り当てる(メモリの連続性を保証する)
4.両方の次元が不明
5.両方の次元が不明で、一度にメモリを割り当てます(メモリの連続性を保証します)
newとdeleteはペアで使用することに注意してください.つまり、どれだけのnewがどれだけのdeleteがあるか、メモリの漏洩を避けることができます.
3.静的2次元配列を関数パラメータとして渡す
上記のいくつかの方法で2次元配列を動的に割り当てると,対応するデータ型を関数パラメータとして用いることができる.ここでは、静的2 D配列が関数パラメータとして渡されることについて説明します.すなわち、次のように呼び出されます.
C言語では静的2次元配列をパラメータとして渡すのは面倒で、一般的には2次元の長さを指定する必要がありますが、2次元の長さが指定されていない場合は、まず1次元ポインタとして渡すしかありません.その後、2次元配列の線形記憶特性を利用して、関数内で指定された要素へのアクセスに変換します.まず、パラメータ伝達の正確性を検証するために、テストコードを作成します.
1.2次元の長さを指定
2.2次元の長さを指定しない
注意:この関数を使用する場合は、2 D配列の先頭アドレスを1 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);
に強制的に変換する必要があります.