Uninitialised value was created by a stack allocation - valgrind

别等时光非礼了梦想. 提交于 2019-12-13 07:41:43

问题


I used valgrind to debug my code with the option track-origins=yes and came across this error.

$ 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)

Line 9 is:

scanf("%d", &t);

I don't understand how this could cause the problem.

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;
}

in:

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

回答1:


valgrind's line number is off: it should have reported 7, not 9, for the allocation line number. The error line 24, however, is correct - the problem is here:

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

The issue is that j loops from 0 to l-1, inclusive, but l is whatever it has been set to in the last iteration of the loop that reads the 2D array, i.e. 4. That's why each time it comes to a line in the array with fewer than 4 entries it reads from uninitialized portion of the array.

The fix is to store lengths of individual rows separately by making l an array l[5], and using l[i] in both loops:

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;
        }


来源:https://stackoverflow.com/questions/33980958/uninitialised-value-was-created-by-a-stack-allocation-valgrind

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!