Valgrind:条件跳转或移动取决于未初始化的值 - 打开文件
Valgrind: Conditional jump or move depends on uninitialised value(s) - opening file
[编辑]:我添加了完整代码。
我必须在 C 的 unix 系统上创建一个简单版本的 "grep" 命令。一切正常,只有 Valgrind 说 Conditional jump or move depends on uninitialised value(s)
.
我想,它可能与我试图打开的文件有关。请在下面查看我的代码。
请注意,我不能在我的代码中使用 <string.h>
。
我在 Ubuntu:
上用 clang 编译代码
cc -pedantic -Wall -Werror -g -std=c99 grep.c -o program
这是 Valgrind 所说的:
lukas@lukas-VirtualBox:~/Desktop/shared/Lab04/prg-hw04$ valgrind --track-origins=yes ./program Mem /proc/meminfo
==2588== Memcheck, a memory error detector
==2588== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2588== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2588== Command: ./program Mem /proc/meminfo
==2588==
==2588== Conditional jump or move depends on uninitialised value(s)
==2588== at 0x4C32D08: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2588== by 0x4EBC9D1: puts (ioputs.c:35)
==2588== by 0x108970: check (grep.c:14)
==2588== by 0x108AA9: read (grep.c:50)
==2588== by 0x108B66: main (grep.c:71)
==2588== Uninitialised value was created by a heap allocation
==2588== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2588== by 0x108A04: read (grep.c:33)
==2588== by 0x108B66: main (grep.c:71)
==2588==
MemTotal: 10461696 kB
MemFree: 7701488 kB
MemAvailable: 8480772 kB
==2588==
==2588== HEAP SUMMARY:
==2588== in use at exit: 0 bytes in 0 blocks
==2588== total heap usage: 4 allocs, 4 frees, 2,700 bytes allocated
==2588==
==2588== All heap blocks were freed -- no leaks are possible
==2588==
==2588== For counts of detected and suppressed errors, rerun with: -v
==2588== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
能帮我定位问题吗?
这是我的 grep.c 文件。
#include <stdio.h>
#include <stdlib.h>
#define SIZE 100
int printed = 1; // return value -> 0 for patter found, 1 for pattern not found
char *pattern;
char *dest;
void check(char *line, int length, int size) {
for (int i = 0; i < length; i++) {
if (line[i] == pattern[0]) {
for (int j = 1; j < size && (i+j) < length; j++) {
if (line[i+j] == pattern[j]) {
if (j==size-1) {
printf("%s\n", line); // print line
printed = 0; // pattern found
goto END;
}
} else {
break;
}
}
}
}
END: ;
}
void read(void) { // read lines, then check individual lines
int c;
int lengthPat = 0;
while(pattern[++lengthPat] != '[=11=]'); // check length of pattern - I can't use string.h library
FILE *file = fopen(dest, "r");
size_t size =100;
char *line = (char*)malloc(size * sizeof(char));
if (line == NULL) //succesfully created malloc?
exit(102);
int last = 0;
if (file != NULL) { // file succesfully opened
while ((c = getc(file)) != EOF) {
if (c != '\n') { // read line until \n
if(last ==size) {
char *p_line = realloc(line, 2*size*sizeof(char));
if (p_line == NULL)
free(line);
line = p_line;
size *= 2;
}
line[last++] = (char)c;
}
else { // end of line, check for pattern
check(line, last, lengthPat);
last = 0;
for (int i = 0; i < size; i++) {
line[i] = '[=11=]';
}
}
}
fclose(file);
free(line);
}
else {
fprintf(stderr, "Error: Could not open file!\n");
}
}
/* The main program */
int main(int argc, char *argv[])
{
if (argc == 3) {
pattern = argv[1];
dest = argv[2];
read();
}
return printed;
}
"connected to the file"是关键。
您的输入文件中有超过 100 个字符的行。用动态增长的堆数组替换堆栈数组。
size_t size =100;
char c_line = malloc(size);
...
if(last ==size)
line = c_line = realloc(c_line, size<<=1);
在解决这个问题时,错误在这一行:
printf("%s\n", line); // print line
line
不是空终止的,因此使用 printf 是一个高级主题。我们这样做:
for (int k = 0; k < length; k++)
putc(line[k], stdout);
putc(line[k], stdout);
问题是字符串 line
末尾缺少空终止符 [=10=]
。
感谢大家的帮助。
[编辑]:我添加了完整代码。
我必须在 C 的 unix 系统上创建一个简单版本的 "grep" 命令。一切正常,只有 Valgrind 说 Conditional jump or move depends on uninitialised value(s)
.
我想,它可能与我试图打开的文件有关。请在下面查看我的代码。
请注意,我不能在我的代码中使用 <string.h>
。
我在 Ubuntu:
cc -pedantic -Wall -Werror -g -std=c99 grep.c -o program
这是 Valgrind 所说的:
lukas@lukas-VirtualBox:~/Desktop/shared/Lab04/prg-hw04$ valgrind --track-origins=yes ./program Mem /proc/meminfo
==2588== Memcheck, a memory error detector
==2588== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2588== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2588== Command: ./program Mem /proc/meminfo
==2588==
==2588== Conditional jump or move depends on uninitialised value(s)
==2588== at 0x4C32D08: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2588== by 0x4EBC9D1: puts (ioputs.c:35)
==2588== by 0x108970: check (grep.c:14)
==2588== by 0x108AA9: read (grep.c:50)
==2588== by 0x108B66: main (grep.c:71)
==2588== Uninitialised value was created by a heap allocation
==2588== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2588== by 0x108A04: read (grep.c:33)
==2588== by 0x108B66: main (grep.c:71)
==2588==
MemTotal: 10461696 kB
MemFree: 7701488 kB
MemAvailable: 8480772 kB
==2588==
==2588== HEAP SUMMARY:
==2588== in use at exit: 0 bytes in 0 blocks
==2588== total heap usage: 4 allocs, 4 frees, 2,700 bytes allocated
==2588==
==2588== All heap blocks were freed -- no leaks are possible
==2588==
==2588== For counts of detected and suppressed errors, rerun with: -v
==2588== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
能帮我定位问题吗?
这是我的 grep.c 文件。
#include <stdio.h>
#include <stdlib.h>
#define SIZE 100
int printed = 1; // return value -> 0 for patter found, 1 for pattern not found
char *pattern;
char *dest;
void check(char *line, int length, int size) {
for (int i = 0; i < length; i++) {
if (line[i] == pattern[0]) {
for (int j = 1; j < size && (i+j) < length; j++) {
if (line[i+j] == pattern[j]) {
if (j==size-1) {
printf("%s\n", line); // print line
printed = 0; // pattern found
goto END;
}
} else {
break;
}
}
}
}
END: ;
}
void read(void) { // read lines, then check individual lines
int c;
int lengthPat = 0;
while(pattern[++lengthPat] != '[=11=]'); // check length of pattern - I can't use string.h library
FILE *file = fopen(dest, "r");
size_t size =100;
char *line = (char*)malloc(size * sizeof(char));
if (line == NULL) //succesfully created malloc?
exit(102);
int last = 0;
if (file != NULL) { // file succesfully opened
while ((c = getc(file)) != EOF) {
if (c != '\n') { // read line until \n
if(last ==size) {
char *p_line = realloc(line, 2*size*sizeof(char));
if (p_line == NULL)
free(line);
line = p_line;
size *= 2;
}
line[last++] = (char)c;
}
else { // end of line, check for pattern
check(line, last, lengthPat);
last = 0;
for (int i = 0; i < size; i++) {
line[i] = '[=11=]';
}
}
}
fclose(file);
free(line);
}
else {
fprintf(stderr, "Error: Could not open file!\n");
}
}
/* The main program */
int main(int argc, char *argv[])
{
if (argc == 3) {
pattern = argv[1];
dest = argv[2];
read();
}
return printed;
}
"connected to the file"是关键。
您的输入文件中有超过 100 个字符的行。用动态增长的堆数组替换堆栈数组。
size_t size =100;
char c_line = malloc(size);
...
if(last ==size)
line = c_line = realloc(c_line, size<<=1);
在解决这个问题时,错误在这一行:
printf("%s\n", line); // print line
line
不是空终止的,因此使用 printf 是一个高级主题。我们这样做:
for (int k = 0; k < length; k++)
putc(line[k], stdout);
putc(line[k], stdout);
问题是字符串 line
末尾缺少空终止符 [=10=]
。
感谢大家的帮助。