我正在尝试为2D数组动态分配内存,然后访问该数组。我收到以下错误: 错误:下标值既不是数组也不是指针也不是向量
int *student; //int student[2][5]
int main() {
student= (int*)malloc(10*sizeof(int));
student[0][1] = 10; //error
printf("student %d \n",student[0][1]); //error
return 0;
}
答案 0 :(得分:1)
2D数组是指向另一个数组的指针,因此,在声明Student时,其类型必须为int **
。
初始化学生时,首先需要为外部指针分配内存,该外部指针将指向内部数组。然后为内部数组分配内存。
int **student; //int student[2][5]
int main() {
student = (int**)malloc(2 * sizeof(int *));
student[0] = (int *)malloc(5 * sizeof(int));
student[0][1] = 10; //error
printf("student %d \n",student[0][1]); //error
return 0;
}
答案 1 :(得分:0)
有几种方法可以做到这一点:
如果您知道在编译时需要多大的尺寸,并且希望行在内存中是连续的,请执行以下操作:
#define ROWS 2
#define COLUMNS 5
...
int (*student)[COLUMNS] = malloc( sizeof *student * ROWS );
...
student[i][j] = some_value;
如果您不知道在编译时需要多大的尺寸,并且您希望行在内存中是连续的,并且您的C版本支持可变长度数组语法(C99或更高版本):>
size_t rows;
size_t columns;
// get rows and columns somehow
int (*student)[columns] = malloc( sizeof *student * rows );
...
student[i][j] = some_value;
严格来说,这将调用未定义的行为,因为VLA上的sizeof
是在运行时评估的,并且student
尚未初始化为指向任何有意义的地方。但是,我和其他人认为这是语言标准措辞中的一个弱点,而且我从来没有像预期的那样工作过。但是请注意,这并不是保证一直在所有地方工作。
如果您不知道在编译时需要多大的尺寸,并且您需要行在内存中是连续的,并且没有可用的可变长度数组:
size_t rows;
size_t columns;
// get rows and columns;
int *student = malloc( sizeof *student * rows * columns );
是的,这是一维数组;您必须将“行”和“列”映射到此一维结构上:
student[i * ROWS + j] = some_value;
如果您不知道在编译时需要多大的尺寸,并且不关心行是否连续,则可以执行以下操作:
size_t rows;
size_t columns;
// get rows and columns;
int **student = malloc( sizeof *student * rows );
if ( student )
{
for ( size_t i = 0; i < rows; i++ )
{
student[i] = malloc( sizeof *student[i] * columns );
}
}
...
student[i][j] = some_value;
对于前三种方法,清理很容易:
free( student );
对于最后一种方法,您必须分别取消分配每个“行”:
for ( size_t i = 0; i < rows; i++ )
free( student[i] );
free( student );