我有用于矩阵乘法的功能,标准三重for循环。
输入是指向两个结构的指针(显示在函数下方)。函数的名称在第125行(第126行为{)。它输出正确的数字,并在多个输入上测试。但是valgrind不喜欢它。
void matrix_mult(matrix_t* matrix_1, matrix_t* matrix_2)
{
int** mult;
mult = calloc(matrix_1 -> height, sizeof(int*));
for (int i; i < (matrix_1 -> height); ++i)
{
mult[i] = calloc(matrix_2 -> width, sizeof(int));
for (int j = 0; j < (matrix_2 -> width); ++j)
{
for (int k = 0; k < (matrix_1 -> width); ++k)
{
mult[i][j] += (matrix_1 -> array[i][k]) * (matrix_2 -> array[k][j]);
}
}
free(matrix_1 -> array[i]);
}
free(matrix_1 -> array);
matrix_1 -> array = mult;
matrix_1 -> width = matrix_2 -> width;
}
而matrix_t是这个结构:
struct matrix
{
int height;
int width;
int** array;
};
valgrind输出为:
==837== Conditional jump or move depends on uninitialised value(s)
==837== at 0x400ED5: matrix_mult (main.c:129)
==837== by 0x400F84: main (main.c:153)
==837== Uninitialised value was created by a stack allocation
==837== at 0x400D6C: matrix_mult (main.c:126)
相同于:
matrix_mult (main.c:131)
matrix_mult (main.c:131)
matrix_mult (main.c:136)
matrix_mult (main.c:139)
最佳答案
上面的代码片段中存在多个问题。for (int i; i < (matrix_1 -> height); ++i)
在这里i
是未初始化的,这很重要,因为i
将包含一个随机(垃圾)值。这样,可以进入或不进入循环。
您似乎假设对calloc
的调用将成功。需要进行错误检查。检查calloc
是否返回NULL,如果是,则处理错误。
冗余代码。
mult = calloc(matrix_1 -> height, sizeof(int*));
for (int i; i < (matrix_1 -> height); ++i)`
{
mult[i] = calloc(matrix_2 -> width, sizeof(int));
// some code
}
一旦解决了未启动的
i
问题,第一次调用calloc
(进入循环之前)就被浪费了,除非struct中的数据使得打算调用函数matrix_mult
而不是循环输入,这很奇怪(?!)。关于c - 未初始化的值是由堆栈分配矩阵mult创建的,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50212614/