【问题标题】:Uninitialised value was created by a stack allocation - valgrind未初始化的值是由堆栈分配创建的 - valgrind
【发布时间】:2015-11-29 08:47:31
【问题描述】:

我使用 valgrind 使用选项 track-origins=yes 调试我的代码并遇到了这个错误。

$ valgrind --track-origins=yes ./frgtnlng < in > out
==7098== 
==7098== Conditional jump or move depends on uninitialised value(s)
==7098==    at 0x4C2F1BC: strcmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7098==    by 0x400857: main (frgtnlng.c:24)
==7098==  Uninitialised value was created by a stack allocation
==7098==    at 0x40064C: main (frgtnlng.c:9)
==7098== 
==7098== Conditional jump or move depends on uninitialised value(s)
==7098==    at 0x40085A: main (frgtnlng.c:24)
==7098==  Uninitialised value was created by a stack allocation
==7098==    at 0x40064C: main (frgtnlng.c:9)

第 9 行是:

scanf("%d", &t);

我不明白这会如何导致问题。

frgtnlng.c:

#include <stdio.h>
#include <string.h>

int main(void)
{
    int t, n, k, l, i, j, z, out[100];
    char f[5][100], m[5][50][50];

    scanf("%d", &t);
    while (t--) {
        for (i = 0; i < 100; i++)
            out[i] = 0;
        scanf("%d%d", &n, &k);
        for (i = 0; i < n; i++)
            scanf("%s", f[i]);
        for (i = 0; i < k; i++) {
            scanf("%d", &l);
            for (j = 0; j < l; j++)
                scanf("%s", m[i][j]);
        }
        for (i = 0; i < k; i++)
            for (j = 0; j < l; j++)
                for (z = 0; z < n; z++) {
                    if (strcmp(m[i][j], f[z]) == 0)
                        out[z] = 1;
                }
        for (i = 0; i < n; i++) {
            if (out[i])
                printf("YES ");
            else
                printf("NO ");
        }
        printf("\n");
    }
    return 0;
}

在:

2
3 2
piygu ezyfo rzotm
1 piygu
6 tefwz tefwz piygu ezyfo tefwz piygu
4 1
kssdy tjzhy ljzym kegqz
4 kegqz kegqz kegqz vxvyj

【问题讨论】:

    标签: c valgrind


    【解决方案1】:

    valgrind 的行号关闭:它应该报告 7,而不是 9,分配行号。但是,第 24 行错误是正确的 - 问题就在这里:

    if (strcmp(m[i][j], f[z]) == 0)
    

    问题在于 j 从 0 循环到 l-1(含),但 l 是在读取二维数组的循环的最后迭代中设置的任何值,即 4。这就是为什么每次遇到数组中少于 4 个条目的行时,它都会从数组的未初始化部分读取。

    解决方法是通过将l 设为数组l[5] 并在两个循环中使用l[i] 来分别存储各个行的长度:

    for (i = 0; i < k; i++) {
        scanf("%d", &l[i]);
        for (j = 0; j < l[i]; j++)
            scanf("%s", m[i][j]);
    }
    for (i = 0; i < k; i++)
        for (j = 0; j < l[i]; j++)
            for (z = 0; z < n; z++) {
                if (strcmp(m[i][j], f[z]) == 0)
                    out[z] = 1;
            }
    

    【讨论】:

    • 包括在内? j 从 0 循环到 l 独占,因为它小于、不小于或等于。区间为 [0,l)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    相关资源
    最近更新 更多