我尝试创建一个动态的5x5整数数组
int **data=malloc(5*5);
但是当我尝试访问它时,出现了分段错误。
您需要为要创建的二维数组分配内存(我认为您已经理解了)。但首先,您需要为指针分配空间,以便存储二维数组的行。
int **data=(int**)malloc(sizeof(*data)*5); //Here 5 is the number of rows
for(int r=0;r<5;r++){
data[r]=(int*)malloc(sizeof(**data)*5);//here 5 is the width of the array
}
data[r*5+c]
。sizeof(int*)
和sizeof(int)
代替sizeof(*data)
和sizeof(**data)
,以避免与*
混淆。malloc
的结果强制转换,应该保持原样。 - Manos Nikolaidismalloc
)。 - user4842163如果你想要一个单一的连续内存块来存储 5x5=25 个整数:
int *data = malloc(5*5*sizeof(*data));
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 ) );
}
free( data );
在第二个例子中,您需要编写以下内容:
for ( size_t i = 0; i < 5; i++ ) free( data[i] );
free( data );
a[i][j]
)并且希望所有数组元素在内存中是连续的,请执行以下操作:int (*data)[5] = malloc( sizeof *data * 5 );
如果你也想在运行时确定数组的大小并且你的编译器支持可变长度数组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 );
__STDC_NO_VLA__
,则应该支持VLAs。sizeof *data
是否被很好地定义存在一些问题;sizeof
表达式通常在编译时计算,但当操作数是VLA时,表达式在运行时计算。data
还没有指向任何东西,尝试解引用无效指针会导致未定义的行为。我只能说我经常使用这个习惯用法,从来没有遇到过问题,但这可能更多是由于运气不好而不是设计问题。