C valgrind 错误
C valgrind errors
以下代码获取一个输入字符串并将其放在堆上,然后打印它:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char input[50] = "BLA BLBA BLA BLA DJAIO JASJDIOA";
char *value = (char*) calloc(1, sizeof(char));
value[0] = '[=10=]';
for (int i = 0; i < strlen(input); i++) {
value = (char*) realloc(value, sizeof(char) * (strlen(value) + 2));
if (value == NULL)
return 1;
value[strlen(value)] = input[i];
value[strlen(value) + 1] = '[=10=]';
}
printf("%s\n", value);
free(value);
return 0;
}
工作完美,但出于某种原因,它从 valgrind 中给出了这些错误:
==109423== Memcheck, a memory error detector
==109423== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==109423== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==109423== Command: ./write_test.o
==109423==
==109423== Conditional jump or move depends on uninitialised value(s)
==109423== at 0x4C2A9E8: strlen (vg_replace_strmem.c:454)
==109423== by 0x400722: main (in /home/me/testing/write_test.o)
==109423==
==109423== Invalid write of size 1
==109423== at 0x40072E: main (in /home/me/testing/write_test.o)
==109423== Address 0x51f4092 is 0 bytes after a block of size 2 alloc'd
==109423== at 0x4C29B78: realloc (vg_replace_malloc.c:785)
==109423== by 0x4006E5: main (in /home/me/testing/write_test.o)
==109423==
==109423== Conditional jump or move depends on uninitialised value(s)
==109423== at 0x4C2A9E8: strlen (vg_replace_strmem.c:454)
==109423== by 0x4006D2: main (in /home/me/testing/write_test.o)
==109423==
==109423== Conditional jump or move depends on uninitialised value(s)
==109423== at 0x4C2A9E8: strlen (vg_replace_strmem.c:454)
==109423== by 0x400703: main (in /home/me/testing/write_test.o)
==109423==
==109423== Conditional jump or move depends on uninitialised value(s)
==109423== at 0x4C2AA08: __GI_strlen (vg_replace_strmem.c:455)
==109423== by 0x4E9FEEB: puts (ioputs.c:36)
==109423== by 0x40075B: main (in /home/me/testing/write_test.o)
==109423==
==109423==
==109423== HEAP SUMMARY:
==109423== in use at exit: 0 bytes in 0 blocks
==109423== total heap usage: 32 allocs, 32 frees, 528 bytes allocated
==109423==
==109423== All heap blocks were freed -- no leaks are possible
==109423==
==109423== For counts of detected and suppressed errors, rerun with: -v
==109423== Use --track-origins=yes to see where uninitialised values come from
==109423== ERROR SUMMARY: 123 errors from 5 contexts (suppressed: 0 from 0)
大小 1 的什么无效写入?什么条件跳跃或移动取决于未初始化的值?
在那行之后
value[strlen(value)] = input[i];
value
不再是 NUL 终止的字符串,因为您刚刚覆盖了 NUL。所以在下一行调用 strlen(value)
并将其用作数组索引调用 UB:
解决方案:
size_t len = strlen(value);
value[len] = input[i];
value[len+1] = '[=11=]';
问题出在这里:
value[strlen(value)] = input[i];
在上一行之后,value
不再指向以 NUL 结尾的字符串,因此下一行的 strlen
将 return 一个不确定的值:
value[strlen(value) + 1] = '[=11=]';
你需要这个:
...
int len = strlen(value);
value[len] = input[i];
value[len + 1] = '[=12=]';
...
以下代码获取一个输入字符串并将其放在堆上,然后打印它:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char input[50] = "BLA BLBA BLA BLA DJAIO JASJDIOA";
char *value = (char*) calloc(1, sizeof(char));
value[0] = '[=10=]';
for (int i = 0; i < strlen(input); i++) {
value = (char*) realloc(value, sizeof(char) * (strlen(value) + 2));
if (value == NULL)
return 1;
value[strlen(value)] = input[i];
value[strlen(value) + 1] = '[=10=]';
}
printf("%s\n", value);
free(value);
return 0;
}
工作完美,但出于某种原因,它从 valgrind 中给出了这些错误:
==109423== Memcheck, a memory error detector ==109423== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==109423== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==109423== Command: ./write_test.o ==109423== ==109423== Conditional jump or move depends on uninitialised value(s) ==109423== at 0x4C2A9E8: strlen (vg_replace_strmem.c:454) ==109423== by 0x400722: main (in /home/me/testing/write_test.o) ==109423== ==109423== Invalid write of size 1 ==109423== at 0x40072E: main (in /home/me/testing/write_test.o) ==109423== Address 0x51f4092 is 0 bytes after a block of size 2 alloc'd ==109423== at 0x4C29B78: realloc (vg_replace_malloc.c:785) ==109423== by 0x4006E5: main (in /home/me/testing/write_test.o) ==109423== ==109423== Conditional jump or move depends on uninitialised value(s) ==109423== at 0x4C2A9E8: strlen (vg_replace_strmem.c:454) ==109423== by 0x4006D2: main (in /home/me/testing/write_test.o) ==109423== ==109423== Conditional jump or move depends on uninitialised value(s) ==109423== at 0x4C2A9E8: strlen (vg_replace_strmem.c:454) ==109423== by 0x400703: main (in /home/me/testing/write_test.o) ==109423== ==109423== Conditional jump or move depends on uninitialised value(s) ==109423== at 0x4C2AA08: __GI_strlen (vg_replace_strmem.c:455) ==109423== by 0x4E9FEEB: puts (ioputs.c:36) ==109423== by 0x40075B: main (in /home/me/testing/write_test.o) ==109423== ==109423== ==109423== HEAP SUMMARY: ==109423== in use at exit: 0 bytes in 0 blocks ==109423== total heap usage: 32 allocs, 32 frees, 528 bytes allocated ==109423== ==109423== All heap blocks were freed -- no leaks are possible ==109423== ==109423== For counts of detected and suppressed errors, rerun with: -v ==109423== Use --track-origins=yes to see where uninitialised values come from ==109423== ERROR SUMMARY: 123 errors from 5 contexts (suppressed: 0 from 0)
大小 1 的什么无效写入?什么条件跳跃或移动取决于未初始化的值?
在那行之后
value[strlen(value)] = input[i];
value
不再是 NUL 终止的字符串,因为您刚刚覆盖了 NUL。所以在下一行调用 strlen(value)
并将其用作数组索引调用 UB:
解决方案:
size_t len = strlen(value);
value[len] = input[i];
value[len+1] = '[=11=]';
问题出在这里:
value[strlen(value)] = input[i];
在上一行之后,value
不再指向以 NUL 结尾的字符串,因此下一行的 strlen
将 return 一个不确定的值:
value[strlen(value) + 1] = '[=11=]';
你需要这个:
...
int len = strlen(value);
value[len] = input[i];
value[len + 1] = '[=12=]';
...