我正在尝试创建一个具有动态比例的矩阵并初始化它 这是我用来分配内存和初始化的代码:
int **matrix;
//mem allocation
matrix=(int*)malloc(sizeof(int*)*mat_w);
for (i=0;i<mat_w;i++)
matrix[i]=(int)malloc(sizeof(int)*mat_h);
//init
for (i=0;i<mat_w;i++)
for (j=0;j<mat_h;j++)
matrix[i][j]=0;
这个,工作正常,问题是,如果我尝试创建一个short类型的矩阵 - 我在init第一次传递时得到分段错误。
这是C语言问题还是我做错了什么?
short
类型矩阵的代码:
short **matrix;
//mem allocation
matrix=(short*)malloc(sizeof(short*)*mat_w);
for (i=0;i<mat_w;i++)
matrix[i]=(short)malloc(sizeof(short)*mat_h);
//init
for (i=0;i<mat_w;i++)
for (j=0;j<mat_h;j++)
matrix[i][j]=0;
P.S。:为了清晰起见,我放弃了安全检查,索引变量和边界声明。
谢谢,
亚历
答案 0 :(得分:17)
malloc()
的返回值的演员表无效。在第一种情况下,它们应为int**
和int*
,在第二种情况下应为short**
和short*
。
当您将malloc()
的返回值强制转换为short
时,返回的指针会被截断以适合short
值,然后被分配给short*
指针,产生指向无效内存位置的指针值。因此,您尝试访问它时会出现分段错误。
使用int
,您很幸运,因为您的平台上很可能sizeof(int)==sizeof(int*)
,因此malloc()
投放到int
的指针不会被截断一切都默默无闻。它很可能在64位平台上以类似的方式崩溃。
应该是:
short **matrix;
matrix=(short**)malloc(sizeof(short*)*mat_w);
for (i=0;i<mat_w;i++)
matrix[i]=(short*)malloc(sizeof(short)*mat_h);
for (i=0;i<mat_w;i++)
for (j=0;j<mat_h;j++)
matrix[i][j]=0;
如果你的代码是纯C(不是C ++),你可以省略强制转换,就像从void*
到任何其他指针类型的C转换有效一样。
short **matrix;
matrix = malloc(sizeof(short*)*mat_w);
for (i=0;i<mat_w;i++)
matrix[i] = malloc(sizeof(short)*mat_h);
for (i=0;i<mat_w;i++)
for (j=0;j<mat_h;j++)
matrix[i][j]=0;
答案 1 :(得分:15)
你使用什么编译器,它不会对你所有这些明显的错误尖叫?
gcc -Wall
使用此代码生成了五条警告消息。
#include <stdlib.h>
int main ()
{
int mat_w = 99;
int mat_h = 666;
int i;
int j;
int **imatrix;
short **smatrix;
//mem allocation
imatrix=(int*)malloc(sizeof(int*)*mat_w);
for (i=0;i<mat_w;i++)
imatrix[i]=(int)malloc(sizeof(int)*mat_h);
//init
for (i=0;i<mat_w;i++)
for (j=0;j<mat_h;j++)
imatrix[i][j]=0;
//mem allocation
smatrix=(short*)malloc(sizeof(short*)*mat_w);
for (i=0;i<mat_w;i++)
smatrix[i]=(short)malloc(sizeof(short)*mat_h);
//init
for (i=0;i<mat_w;i++)
for (j=0;j<mat_h;j++)
smatrix[i][j]=0;
return 0;
}
给我
malloc.c: In function 'main':
malloc.c:13: warning: assignment from incompatible pointer type
malloc.c:15: warning: assignment makes pointer from integer without a cast
malloc.c:22: warning: assignment from incompatible pointer type
malloc.c:24: warning: cast from pointer to integer of different size
malloc.c:24: warning: assignment makes pointer from integer without a cast
答案 2 :(得分:6)
你必须从这个错误中吸取教训。它说: 永远不会投出'malloc'的结果 。
此外,这是一个更好的实践指导原则的一部分,只要有可能,最好遵循: 永远不会在代码中提及类型名称,但声明 除外。< / p>
这是您的代码应该从一开始就看起来的方式
int **matrix;
matrix = malloc(mat_w * sizeof *matrix);
for (i = 0; i < mat_w; i++)
matrix[i] = malloc(mat_h * sizeof *matrix[i]);
for (i = 0; i < mat_w; i++)
for (j = 0; j < mat_h; j++)
matrix[i][j] = 0;
注意,为了在这个版本中从'int'切换到'short',你只需要更改'matrix'的声明而不需要其他任何内容。
(当然,在这段代码中可以改进更多内容,但我只是想解决错误的直接原因。)
答案 3 :(得分:5)
您正在将int**
转换为int*
malloc的返回值(简称相同)。 malloc
应该用作:
matrix = (int**)malloc(sizeof(int*) * mat_w);
或
matrix = (short**)malloc(sizeof(short*) * mat_w);
矩阵内的每个分配都相同:
matrix[i] = (int*)malloc(sizeof(int) * mat_h);
或
matrix[i] = (short*)malloc(sizeof(short) * mat_h);
答案 4 :(得分:2)
是的,你做错了什么。
int *matrix;
表示matrix
是一个整数数组。如果你想让它成为一个整数数组的数组,你应该这样声明:
int **matrix;
//mem allocation
matrix=(int**)malloc(sizeof(int*)*mat_w);
for (i=0; i<mat_w; i++)
matrix[i]=(int*)malloc(sizeof(int)*mat_h);
//init
for (i=0; i<mat_w; i++)
for (j=0; j<mat_h; j++)
matrix[i][j]=0;
当然,如果你事先知道矩阵的尺寸,就这样做:
int matrix[mat_w][mat_h];
//init
for (i=0; i<mat_w; i++)
for (j=0; j<mat_h; j++)
matrix[i][j]=0;
答案 5 :(得分:0)
sizeof(int)
等于特定系统的总线宽度。您试图将32位(或64位,具体取决于您的平台)地址值放入16位分配的内存。
查看Checkers帖子中的第二个例子。这是内存分配的正确和可取的方法。