我如何在c中使用动态二维数组
How can i use dynamic 2d array in c
我尝试制作一个动态的 5x5 整数数组
int **data=malloc(5*5);
但是我在尝试访问它时遇到分段错误。
你需要为你想要制作的二维数组分配内存(我想你明白了)。但首先,您必须为将存储二维数组行的指针分配 space。
int **data=(int**)malloc(sizeof(*data)*5); //Here 5 is the number of rows
现在您可以为每一行分配 space。
for(int r=0;r<5;r++){
data[r]=(int*)malloc(sizeof(**data)*5);//here 5 is the width of the array
}
如果您想要整个数组的连续内存块,您可以分配一个大小为 25 的单维数组,然后像 data[r*5+c]
一样访问它。
PS:您可以使用 sizeof(int*)
和 sizeof(int)
来代替 sizeof(*data)
和 sizeof(**data)
,以避免与 *
[= 混淆18=]
PS:如果你不使用 C++,从 malloc 的 return 值中移除强制转换更好(见评论)。
如果你想要一个连续的内存块来保存 5x5=25 个整数:
int *data = malloc(5*5*sizeof(*data));
如果你想要一个大小为 5x5 的二维数组
int **data = malloc(5*sizeof(*data));
for (int i=0; i<5; ++i)
data[i] = malloc(5*sizeof(**data));
有两种可能。第一个确实是分配一个二维数组:
int ( *data )[5] = malloc( 5 * 5 * sizeof( int ) );
在这种情况下,为数组分配了一个连续的范围。
第二种是先分配一个一维的指针数组,再分配已经分配的指针指向的一维数组
例如
int **data = malloc( 5 * sizeof( int * ) );
for ( size_t i = 0; i < 5; i++ )
{
data[i] = malloc( 5 * sizeof( int ) );
}
在这种情况下,实际上分配了 6 个内存范围:一个用于指针数组,另外 5 个用于整数数组。
要释放第一个例子中分配的内存,写
就足够了
free( data );
而在第二个例子中你需要编写以下内容
for ( size_t i = 0; i < 5; i++ ) free( data[i] );
free( data );
答案如下:
int ** squaredMatrix;
int szMatrix=10;
squaredMatrix= (int**)malloc(szMatrix*sizeof(int*));
为了制作二维数组,您应该将它们视为一个数组,每个块又是一个数组。
比如上图中,蓝色方块组成一个数组,每个蓝色方块指向一个数组(每4行绿色方块是一个数组,一列蓝色方块是主数组)
如果您想将数组视为二维数组 (a[i][j]
) 并且您希望所有数组元素在内存中都是连续的,请执行以下操作:
int (*data)[5] = malloc( sizeof *data * 5 );
如果你也想在运行时table确定数组的大小和你的编译器支持变长数组1:
size_t rows, cols;
...
int (*data)[rows] = malloc( sizeof *data * cols );<sup>2</sup>
如果您的编译器 不 支持 VLA,而您仍想在 运行 时确定数组大小,您可以这样做:
size_t rows, cols;
...
int **data = malloc( sizeof *data * rows );
if ( data )
{
for ( size_t i = 0; i < rows; i++ )
{
data[i] = malloc( sizeof *data[i] * cols );
}
}
这种方法的缺点是不能保证数组的行在内存中是连续的(它们很可能不会)。 行中 的元素将是连续的,但行之间将不连续。
如果您想在 运行 时确定数组大小 和 让所有数组元素在内存中都是连续的 但是 你的编译器不支持可变长度数组,你需要分配一个一维数组并手动计算你的索引 (a[i * rows + j]
):
int *data = malloc( sizeof *data * rows * cols );
1。 VLA 是在 C99 中引入的,但在 C2011 中成为可选的。 post-C99 编译器 不 定义宏 __STDC_NO_VLA__
应该支持 VLA。
2. 注意——在这个例子中 sizeof *data
是否定义明确存在疑问; sizeof
表达式通常在编译时求值,但当操作数是 VLA 时,表达式在 运行 时求值。 data
还没有指向任何东西,试图解引用一个无效的指针会导致未定义的行为。我只能说我经常使用这个习惯用法,从来没有遇到过问题,但这可能更多是因为运气而不是设计。
我尝试制作一个动态的 5x5 整数数组
int **data=malloc(5*5);
但是我在尝试访问它时遇到分段错误。
你需要为你想要制作的二维数组分配内存(我想你明白了)。但首先,您必须为将存储二维数组行的指针分配 space。
int **data=(int**)malloc(sizeof(*data)*5); //Here 5 is the number of rows
现在您可以为每一行分配 space。
for(int r=0;r<5;r++){
data[r]=(int*)malloc(sizeof(**data)*5);//here 5 is the width of the array
}
如果您想要整个数组的连续内存块,您可以分配一个大小为 25 的单维数组,然后像 data[r*5+c]
一样访问它。
PS:您可以使用 sizeof(int*)
和 sizeof(int)
来代替 sizeof(*data)
和 sizeof(**data)
,以避免与 *
[= 混淆18=]
PS:如果你不使用 C++,从 malloc 的 return 值中移除强制转换更好(见评论)。
如果你想要一个连续的内存块来保存 5x5=25 个整数:
int *data = malloc(5*5*sizeof(*data));
如果你想要一个大小为 5x5 的二维数组
int **data = malloc(5*sizeof(*data));
for (int i=0; i<5; ++i)
data[i] = malloc(5*sizeof(**data));
有两种可能。第一个确实是分配一个二维数组:
int ( *data )[5] = malloc( 5 * 5 * sizeof( int ) );
在这种情况下,为数组分配了一个连续的范围。
第二种是先分配一个一维的指针数组,再分配已经分配的指针指向的一维数组
例如
int **data = malloc( 5 * sizeof( int * ) );
for ( size_t i = 0; i < 5; i++ )
{
data[i] = malloc( 5 * sizeof( int ) );
}
在这种情况下,实际上分配了 6 个内存范围:一个用于指针数组,另外 5 个用于整数数组。
要释放第一个例子中分配的内存,写
就足够了free( data );
而在第二个例子中你需要编写以下内容
for ( size_t i = 0; i < 5; i++ ) free( data[i] );
free( data );
答案如下:
int ** squaredMatrix;
int szMatrix=10;
squaredMatrix= (int**)malloc(szMatrix*sizeof(int*));
为了制作二维数组,您应该将它们视为一个数组,每个块又是一个数组。
比如上图中,蓝色方块组成一个数组,每个蓝色方块指向一个数组(每4行绿色方块是一个数组,一列蓝色方块是主数组)
如果您想将数组视为二维数组 (a[i][j]
) 并且您希望所有数组元素在内存中都是连续的,请执行以下操作:
int (*data)[5] = malloc( sizeof *data * 5 );
如果你也想在运行时table确定数组的大小和你的编译器支持变长数组1:
size_t rows, cols;
...
int (*data)[rows] = malloc( sizeof *data * cols );<sup>2</sup>
如果您的编译器 不 支持 VLA,而您仍想在 运行 时确定数组大小,您可以这样做:
size_t rows, cols;
...
int **data = malloc( sizeof *data * rows );
if ( data )
{
for ( size_t i = 0; i < rows; i++ )
{
data[i] = malloc( sizeof *data[i] * cols );
}
}
这种方法的缺点是不能保证数组的行在内存中是连续的(它们很可能不会)。 行中 的元素将是连续的,但行之间将不连续。
如果您想在 运行 时确定数组大小 和 让所有数组元素在内存中都是连续的 但是 你的编译器不支持可变长度数组,你需要分配一个一维数组并手动计算你的索引 (a[i * rows + j]
):
int *data = malloc( sizeof *data * rows * cols );
1。 VLA 是在 C99 中引入的,但在 C2011 中成为可选的。 post-C99 编译器 不 定义宏
__STDC_NO_VLA__
应该支持 VLA。2. 注意——在这个例子中
sizeof *data
是否定义明确存在疑问; sizeof
表达式通常在编译时求值,但当操作数是 VLA 时,表达式在 运行 时求值。 data
还没有指向任何东西,试图解引用一个无效的指针会导致未定义的行为。我只能说我经常使用这个习惯用法,从来没有遇到过问题,但这可能更多是因为运气而不是设计。