未初始化的值是由堆栈分配创建的 - valgrind
Uninitialised value was created by a stack allocation - valgrind
我使用 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
valgrind 的行号已关闭:它应该为分配行号报告 7,而不是 9。然而,错误行 24 是正确的 - 问题在这里:
if (strcmp(m[i][j], f[z]) == 0)
问题是 j
从 0 循环到 l-1
,包括在内,但是 l
是在 last[=25 中设置的任何值=] 读取二维数组的循环迭代,即 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;
}
我使用 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
valgrind 的行号已关闭:它应该为分配行号报告 7,而不是 9。然而,错误行 24 是正确的 - 问题在这里:
if (strcmp(m[i][j], f[z]) == 0)
问题是 j
从 0 循环到 l-1
,包括在内,但是 l
是在 last[=25 中设置的任何值=] 读取二维数组的循环迭代,即 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;
}