我正在使用此函数来读取输入矩阵:
void leMatInt(int **M,int linhas,int colunas){
int i, j;
for (i = 0; i < linhas; i++){
for (j = 0; j < colunas; j++){
scanf("%d", &M[i][j]);
//printf("Leu [%d, %d]n", i, j);
}
}
}
我正在像这样创建矩阵:
scanf("%d", &v1);
int **matriz1=(int **)malloc(v1 * sizeof(int));
for(i = 0;i < v1; i++){
matriz1[i] = (int *)malloc(v1 * sizeof(int));
}
leMatInt(matriz1, v1, v1);
该代码适用于 v1 <= 4,但如果我尝试输入 5v5 矩阵,代码会在函数中出现运行时错误。
matriz1
是一个双指针,所以在分配内存时你应该写sizeof(int*)
.因为** pointer
将保存/包含* single
指针。
int **matriz1 = malloc(v1 * sizeof(int*));
for(i = 0;i < v1; i++){
matriz1[i] = malloc(v1 * sizeof(int));
}
不建议使用类型转换malloc()
。
int **matriz1=malloc(v1 * sizeof(int*));
双精度(**
(指针变量将保存pointer to an int
。
matriz1
是指向指针变量的指针(指向int*
的指针(。
因此,它将包含int*
变量。
此外,不需要强制转换malloc
的返回类型,并检查 malloc
的返回值。
这是未定义的行为。这就是为什么它意外地适用于4
,但不适用于5x5
矩阵。
一个例子:(考虑特定情况(-
虽然
sizeof int
是实现定义的,但它通常是4
字节。但是 sizeof 指针在 64 位编译器中通常为8
个字节。现在要容纳 5 个
int*
变量,您需要40
字节。但是您正在分配20
字节。因此,您分配的内存少于所需内存。和 访问不允许的内存,调用未定义 行为。
int **matriz1=(int **)malloc(v1 * sizeof(int));
这句话是错误的。正如其他答案已经指出的那样,matriz1
指向的元素不是整数,而是指向整数的指针,因此此处应sizeof(int *)
使用带有类型名称的sizeof
。
此外,强制转换 malloc()
的返回值是不必要的,并且可以说是 C 中的糟糕风格。
为了避免这样的错误,sizeof
还可以将表达式作为操作数,并使用此表达式将计算的类型,这对于malloc()
非常方便 - 它应该看起来像这样:
int **matriz1 = malloc(v1 * sizeof *matriz1);
如果您稍后更改matriz1
的类型,sizeof *matriz1
仍然会给出正确的元素大小 - 它是 matriz1 指向的任何大小。