Valgrind 错误、大小读取无效和条件跳转或移动取决于未初始化的值
Valgrind errors, Invalid read of size & conditional jump or move depens on uninitialised value
我遇到了这两个错误,在搜索了很长时间后可能需要一些帮助才能找到解决方案:
==4902== 1 errors in context 1 of 2:
==4902== Invalid read of size 1
==4902== at 0x4010A0: getData (main.c:321)
==4902== by 0x402527: main (main.c:783)
==4902== Address 0x52007af is 1 bytes before a block of size 2,152 alloc'd
==4902== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4902== by 0x400FF1: getData (main.c:309)
==4902== by 0x402527: main (main.c:783)
==4902==
==4902==
==4902== 1 errors in context 2 of 2:
==4902== Conditional jump or move depends on uninitialised value(s)
==4902== at 0x4C2E0E9: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4902== by 0x40107A: getData (main.c:319)
==4902== by 0x402527: main (main.c:783)
==4902== Uninitialised value was created by a heap allocation
==4902== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4902== by 0x400FF1: getData (main.c:309)
==4902== by 0x402527: main (main.c:783)
char** buffer = malloc(file_size * sizeof(char**));
if(buffer == NULL)
{
status = EXITCODE_4;
return status;
}
int buffer_counter = 0;
int buffer_length = 0;
while(!feof(datafile))
{
buffer[buffer_counter] = malloc(file_size * sizeof(char*));
if(buffer[buffer_counter] == NULL)
{
status = EXITCODE_4;
free2D(buffer, buffer_counter);
return status;
}
fgets(buffer[buffer_counter], file_size, datafile);
buffer_length = strlen(buffer[buffer_counter]) - 1;
if((buffer[buffer_counter][buffer_length]) == NEWLINE)
buffer[buffer_counter][buffer_length] = 0;
buffer_counter++;
}
第 309 行是第二个 malloc 发生的地方,
321 如果
和 319 strlen
我对 valgrind 不是很有经验,所以我不知道如何解决这个问题。
感谢我能得到的任何帮助。
改变
while (!feof(datafile))
和
while (fgets(buffer[buffer_counter], file_size, datafile) != NULL)
因为while (!feof(datafile))
会迭代一次超出文件末尾,读取why while (!feof(datafile))
is always wrong。
EOF
标记是在 fgets()
尝试读取文件末尾之后设置的,因此它需要一次额外的迭代才能发生,但是 fgets()
将 return NULL
在文件的末尾,所以如果你在 while
循环条件下测试它,你将不会访问未初始化的值。
当然你需要重新考虑程序流程,我建议这样
char** buffer = malloc(file_size * sizeof(char *));
if (buffer == NULL)
{
status = EXITCODE_4;
return status;
}
int buffer_counter = 0;
int buffer_length = 0;
char line[file_size];
while (fgets(line, file_size, datafile) != NULL)
{
size_t length;
length = strlen(line);
if (line[length - 1] == NEWLINE)
line[--length] = '[=12=]';
buffer[buffer_counter] = malloc(1 + length);
if (buffer[buffer_counter] == NULL)
{
status = EXITCODE_4;
free2D(buffer, buffer_counter);
return status;
}
strcpy(buffer[buffer_counter], line);
buffer_counter++;
}
此外,malloc(file_size * sizeof(char *))
正在分配比您需要更多的内存,您需要 malloc(file_size * sizeof(char))
,而 sizeof(char) == 1
所以只是 malloc(file_size)
,我还是修复了分配 space 为适合的确切字符串。
这是针对这些问题的建议修复方法
char** buffer = malloc(file_size * sizeof(char**));
if(buffer == NULL)
{
status = EXITCODE_4;
return status;
}
// implied else, malloc successful
// clear list of pointer to NULLs
memset( buffer, 0x00, (file_size* sizeof(char**) ) );
int buffer_counter = 0;
int buffer_length = 0;
while(0 < (buffer_length = getline( buffer[buffer_counter], file_size, datafile)))
{
if ( 0 >= buffer_length )
{
status = EXITCODE_4;
free2D(buffer, buffer_counter);
return status;
}
// implied else, getline successful
if((buffer[buffer_counter][buffer_length-1]) == NEWLINE)
{
// trim newline
buffer[buffer_counter][buffer_length-1] = '[=10=]';
buffer_length--;
}
buffer_counter++;
} // end while
我遇到了这两个错误,在搜索了很长时间后可能需要一些帮助才能找到解决方案:
==4902== 1 errors in context 1 of 2:
==4902== Invalid read of size 1
==4902== at 0x4010A0: getData (main.c:321)
==4902== by 0x402527: main (main.c:783)
==4902== Address 0x52007af is 1 bytes before a block of size 2,152 alloc'd
==4902== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4902== by 0x400FF1: getData (main.c:309)
==4902== by 0x402527: main (main.c:783)
==4902==
==4902==
==4902== 1 errors in context 2 of 2:
==4902== Conditional jump or move depends on uninitialised value(s)
==4902== at 0x4C2E0E9: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4902== by 0x40107A: getData (main.c:319)
==4902== by 0x402527: main (main.c:783)
==4902== Uninitialised value was created by a heap allocation
==4902== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4902== by 0x400FF1: getData (main.c:309)
==4902== by 0x402527: main (main.c:783)
char** buffer = malloc(file_size * sizeof(char**));
if(buffer == NULL)
{
status = EXITCODE_4;
return status;
}
int buffer_counter = 0;
int buffer_length = 0;
while(!feof(datafile))
{
buffer[buffer_counter] = malloc(file_size * sizeof(char*));
if(buffer[buffer_counter] == NULL)
{
status = EXITCODE_4;
free2D(buffer, buffer_counter);
return status;
}
fgets(buffer[buffer_counter], file_size, datafile);
buffer_length = strlen(buffer[buffer_counter]) - 1;
if((buffer[buffer_counter][buffer_length]) == NEWLINE)
buffer[buffer_counter][buffer_length] = 0;
buffer_counter++;
}
第 309 行是第二个 malloc 发生的地方, 321 如果 和 319 strlen
我对 valgrind 不是很有经验,所以我不知道如何解决这个问题。 感谢我能得到的任何帮助。
改变
while (!feof(datafile))
和
while (fgets(buffer[buffer_counter], file_size, datafile) != NULL)
因为while (!feof(datafile))
会迭代一次超出文件末尾,读取why while (!feof(datafile))
is always wrong。
EOF
标记是在 fgets()
尝试读取文件末尾之后设置的,因此它需要一次额外的迭代才能发生,但是 fgets()
将 return NULL
在文件的末尾,所以如果你在 while
循环条件下测试它,你将不会访问未初始化的值。
当然你需要重新考虑程序流程,我建议这样
char** buffer = malloc(file_size * sizeof(char *));
if (buffer == NULL)
{
status = EXITCODE_4;
return status;
}
int buffer_counter = 0;
int buffer_length = 0;
char line[file_size];
while (fgets(line, file_size, datafile) != NULL)
{
size_t length;
length = strlen(line);
if (line[length - 1] == NEWLINE)
line[--length] = '[=12=]';
buffer[buffer_counter] = malloc(1 + length);
if (buffer[buffer_counter] == NULL)
{
status = EXITCODE_4;
free2D(buffer, buffer_counter);
return status;
}
strcpy(buffer[buffer_counter], line);
buffer_counter++;
}
此外,malloc(file_size * sizeof(char *))
正在分配比您需要更多的内存,您需要 malloc(file_size * sizeof(char))
,而 sizeof(char) == 1
所以只是 malloc(file_size)
,我还是修复了分配 space 为适合的确切字符串。
这是针对这些问题的建议修复方法
char** buffer = malloc(file_size * sizeof(char**));
if(buffer == NULL)
{
status = EXITCODE_4;
return status;
}
// implied else, malloc successful
// clear list of pointer to NULLs
memset( buffer, 0x00, (file_size* sizeof(char**) ) );
int buffer_counter = 0;
int buffer_length = 0;
while(0 < (buffer_length = getline( buffer[buffer_counter], file_size, datafile)))
{
if ( 0 >= buffer_length )
{
status = EXITCODE_4;
free2D(buffer, buffer_counter);
return status;
}
// implied else, getline successful
if((buffer[buffer_counter][buffer_length-1]) == NEWLINE)
{
// trim newline
buffer[buffer_counter][buffer_length-1] = '[=10=]';
buffer_length--;
}
buffer_counter++;
} // end while