首页 > 解决方案 > 未初始化的值是由堆栈分配矩阵 mult 创建的

问题描述

我有这个函数用于矩阵乘法,标准三重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)

标签: cvalgrind

解决方案


上面的代码片段中有多个问题。

  • for (int i; i < (matrix_1 -> height); ++i)i是未初始化的,这是一个问题,因为i它将包含一个随机(垃圾)值。这样,可以进入也可以不进入循环。
  • 您似乎认为调用 tocalloc会成功。需要进行错误检查。检查是否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打算被调用但没有进入循环,这会很奇怪(?! )。


推荐阅读