Calloc()错误强制关闭程序,调试器不可见
我试图实现一个函数,该函数将两个动态矩阵(AxB)相乘,并返回指向动态分配产品(C)的指针。函数的参数为:Calloc()错误强制关闭程序,调试器不可见,c,heap,matrix-multiplication,C,Heap,Matrix Multiplication,我试图实现一个函数,该函数将两个动态矩阵(AxB)相乘,并返回指向动态分配产品(C)的指针。函数的参数为: 指向矩阵A的指针 a_行,a中的行数 列中的列数 指向矩阵B的指针 b_cols,b中的列数 由于产品将具有与A相同的行数和与B相同的列数,因此使用A_行和B_列来确定要分配的产品的大小 该功能如图所示: double** MatrixMultiply( double** a, const uint32_t a_rows, const uint32_t a_cols
double** MatrixMultiply(
double** a,
const uint32_t a_rows,
const uint32_t a_cols,
double** b,
const uint32_t b_cols) {
double** c;
c = (double**) calloc(a_rows, sizeof(double**)); //product matrix C has
//matrix A rows and Matrix B cols
for(int32_t i = 0; i < a_rows; i++) {
c[i] = (double*) calloc(b_cols, sizeof(double*));
}
for(uint32_t i = 0; i < a_rows; i++) {
for(uint32_t j = 0; j < b_cols; j++) {
for(uint32_t k = 0; k < a_cols; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
return c;
}
double**MatrixMultiply(
双**a,
共32行,
警察局,
双**b,
const uint32_t b_cols){
双**c;
c=(double**)calloc(a_行,sizeof(double**));//乘积矩阵c
//矩阵A行和矩阵B列
对于(int32_t i=0;i
问题是,每当我运行我的程序时,它都会被函数崩溃,因为我认为这是某种分段错误。但是,每当我运行调试器并逐行检查每一行时,它都不会显示发生了任何错误
令我感到奇怪的是,当我将“a_rows”和“b_cols”更改为常量(例如,20)时,函数运行正常。是什么导致了这个问题?如何修复呢?非常感谢您的帮助。您的代码错误
calloc
(和malloc
)可能会失败,您应该始终处理这个问题。您不需要强制转换它,第二个参数是每个单元格的大小(不是指向它的指针)
你应该有一个最低限度
double** c= calloc(a_rows, sizeof(double*));
if (c==NULL) { perror("calloc c"); exit(EXIT_FAILURE); }
同样地
c[i] = calloc(b_cols, sizeof(double));
if (c[i]==NULL) { perror("calloc c row"); exit(EXIT_FAILURE); };
请注意,对于每个calloc
,第二个参数是一个单元格的大小(而不是指向它的指针的大小)。第一个参数是单元格数(您确定要b_cols
,而不是a_cols
?只有您知道)
对于c
的整体分配,实际上所有指针的大小都相同,因此sizeof(double**)
的值(在我的Linux/x86-64上为8字节)通常与sizeof(double*)
相同
您应该使用所有警告和调试信息进行编译:gcc-Wall-Wextra-g
。某些编译器(的最新版本)可能会警告您。您可以使用来运行(带有检查)您的程序(可能检测到缓冲区溢出)。当然你也应该
顺便说一句,拥有矩阵的一个更好的方法是使它们成为某种抽象数据类型,如
但是,每当我运行调试器并逐行检查每一行时,它都不会显示发生了任何错误
在Linux(或MacOSX)上,您可以设置您的系统,以便发生核心转储(请确保对您的核心文件有足够大的限制,可能是使用
bash的ulimit
内置),并使用gdb
对该核心转储进行事后分析;看见并且,gdb
能够运行您的程序直到崩溃。您分配了错误的内存量
c[i] = (double*) calloc(b_cols, sizeof(double*));
这为双指针的b_cols
分配内存,而不是双指针的b_cols
这是使用typedef()
时出现的典型错误,错误非常严重
很简单,因为您在不需要的地方添加了*
,或者在需要的时候忘记了添加*
使用sizeof*var
比使用sizeof()更好:
sizeof*arr
返回准确的字节数,而不考虑类型。信息技术
还有一个好处是,如果您以后碰巧更改了
变量,您不必担心更改内部的表达式
sizeof
正确的方法是:
c = calloc(a_rows, sizeof *c);
if(c == NULL)
{
// error handling
}
for(int32_t i = 0; i < a_rows; i++) {
c[i] = calloc(b_cols, sizeof *c[i]);
if(c[i] == NULL)
{
// error handling
}
}
c=calloc(a_行,sizeof*c);
如果(c==NULL)
{
//错误处理
}
对于(int32_t i=0;i
还要始终检查结果是否为空。如果
如果不进行检查,结果为NULL
,则您将尝试访问NULL
未定义行为并将导致segfault的指针。也不要
以后忘了释放内存。您所有的内存分配都已中断:您将错误的类型传递给了sizeof
,您不应该强制转换calloc()
。请发布a。您从未初始化a行
,b列
…这是一个指向抽象数据解决方案的位置良好的链接<代码>:)
c = calloc(a_rows, sizeof *c);
if(c == NULL)
{
// error handling
}
for(int32_t i = 0; i < a_rows; i++) {
c[i] = calloc(b_cols, sizeof *c[i]);
if(c[i] == NULL)
{
// error handling
}
}