我尝试制作动态5x5 int数组
int **data=malloc(5*5);
但是在尝试访问它时会出现分段错误。
答案 0 :(得分:7)
您需要为要制作的2d阵列分配内存(我认为您理解)。但首先,您必须为存储2D数组行的指针分配空间。
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
}
如果您想要整个阵列的连续内存块,您可以分配大小为25的单维数组,并像data[r*5+c]
一样访问它。
PS:您可以使用sizeof(*data)
和sizeof(**data)
代替sizeof(int*)
和sizeof(int)
,以避免与*
混淆
PS:如果你没有使用C ++,那么从malloc的返回值中删除强制转换更好(参见注释)。
答案 1 :(得分:4)
如果您希望单个连续内存块保持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));
答案 2 :(得分:3)
有两种可能性。第一个确实要分配一个二维数组:
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个内存区:一个用于指针数组,另外一个用于整数数组。
要在第一个示例中释放已分配的内存,只需编写
即可free( data );
在第二个例子中,您需要编写以下内容
for ( size_t i = 0; i < 5; i++ ) free( data[i] );
free( data );
答案 3 :(得分:0)
如果要将数组视为2D数组(a[i][j]
)和,您希望所有数组元素在内存中连续,请执行以下操作:
int (*data)[5] = malloc( sizeof *data * 5 );
如果你还想成为表来确定运行时和的数组大小,你的编译器支持可变长度数组 1 :
size_t rows, cols;
...
int (*data)[rows] = malloc( sizeof *data * cols );2
如果您的编译器不支持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。 VAs引入了VGA,但随后在C2011中可选。 不定义宏
__STDC_NO_VLA__
的C99后编译器应支持VLA。sizeof *data
是否定义明确存在一些问题; sizeof
表达式通常在编译时计算,但是当操作数是VLA时,表达式在运行时计算。 data
未指向任何内容,并且尝试取消引用无效指针会导致未定义的行为。我可以说的是,我经常使用这个成语而从来没有问题,但这可能更多是因为运气不好而不是设计。
答案 4 :(得分:-1)