C Valgrind错误,尺寸和尺寸的读取无效;条件跳转或移动取决于未初始化的值
我有这两个错误,在搜索了很长时间后,可能需要一些帮助来找到解决方案:C Valgrind错误,尺寸和尺寸的读取无效;条件跳转或移动取决于未初始化的值,c,valgrind,C,Valgrind,我有这两个错误,在搜索了很长时间后,可能需要一些帮助来找到解决方案: ==4902==1上下文中的错误,共2个: ==4902==大小为1的读取无效 ==4902==at 0x401A0:getData(main.c:321) ==4902==0x402527:main(main.c:783) ==4902==地址0x52007af是分配大小为2152的块之前的1个字节 ==4902==at 0x4C2AB80:malloc(在/usr/lib/valgrind/vgpreload_memch
==4902==1上下文中的错误,共2个:
==4902==大小为1的读取无效
==4902==at 0x401A0:getData(main.c:321)
==4902==0x402527:main(main.c:783)
==4902==地址0x52007af是分配大小为2152的块之前的1个字节
==4902==at 0x4C2AB80:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==4902==by 0x400FF1:getData(main.c:309)
==4902==0x402527:main(main.c:783)
==4902==
==4902==
==4902==2个上下文中的1个错误,共2个:
==4902==条件跳转或移动取决于未初始化的值
==4902==at 0x4C2E0E9:strlen(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==4902==by 0x40107A:getData(main.c:319)
==4902==0x402527:main(main.c:783)
==4902==堆分配创建了未初始化的值
==4902==at 0x4C2AB80:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==4902==by 0x400FF1:getData(main.c:309)
==4902==0x402527:main(main.c:783)
char**buffer=malloc(文件大小*sizeof(char**));
if(buffer==NULL)
{
状态=EXITCODE_4;
返回状态;
}
int buffer_计数器=0;
int buffer_length=0;
而(!feof(数据文件))
{
buffer[buffer\u counter]=malloc(文件大小*sizeof(char*));
if(缓冲区[缓冲区计数器]==NULL)
{
状态=EXITCODE_4;
free2D(缓冲区、缓冲区计数器);
返回状态;
}
fgets(缓冲区[缓冲区计数器]、文件大小、数据文件);
缓冲区长度=strlen(缓冲区[缓冲区计数器])-1;
if((buffer[buffer\u counter][buffer\u length])==换行符)
缓冲区[缓冲区计数器][缓冲区长度]=0;
缓冲区_计数器++;
}
第309行是第二个malloc发生的地方,
321国际单项体育联合会
斯特伦319号
我对valgrind不是很有经验,所以我不知道如何解决这个问题。
谢谢您的帮助。更改
while (!feof(datafile))
与
因为而(!feof(datafile))
将在文件末尾之外迭代一次,所以读取
EOF
标记是在fgets()
尝试读取文件末尾之后设置的,因此需要进行一次额外的迭代,但fgets()
将在文件末尾返回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] = '\0';
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)
,我已经修复了它,为精确的字符串分配了空间。这里是解决问题的建议方法
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] = '\0';
buffer_length--;
}
buffer_counter++;
} // end while
char**buffer=malloc(文件大小*sizeof(char**));
if(buffer==NULL)
{
状态=EXITCODE_4;
返回状态;
}
//否则,malloc成功了
//清除指向空值的指针列表
memset(缓冲区,0x00,(文件大小*sizeof(char**));
int buffer_计数器=0;
int buffer_length=0;
而(0<(缓冲区长度=getline(缓冲区[缓冲区计数器]、文件大小、数据文件)))
{
如果(0>=缓冲区长度)
{
状态=EXITCODE_4;
free2D(缓冲区、缓冲区计数器);
返回状态;
}
//否则,getline成功
if((buffer[buffer\u counter][buffer\u length-1])==换行符)
{
//修剪换行符
缓冲区[缓冲区计数器][缓冲区长度-1]='\0';
缓冲区长度--;
}
缓冲区_计数器++;
}//结束时
while(!feof(datafile))
这行:''buffer[buffer\u counter]=malloc(file\u size*sizeof(char*));应该是:'buffer[buffer_counter]=malloc(文件大小);'因为需要一个char数组,而不是指向char的指针数组,所以应该将初始malloc'd数组清除为all NULL,以便在释放所有内存分配时(相对而言)更容易。建议在while循环之前执行第一行分配,并使用fgets()控制while循环——或者使用getline()然后,除了指针的初始列表之外,没有对malloc的单独调用。char**buffer=malloc(file_size*sizeof(char**))代码>也会导致错误的数据类型。要避免此错误,请使用sizeof*buffer
而不是命名类型explicitly@PinkieClownie顺便说一下,我很高兴看到您检查malloc()
的返回值。保持那种风格,相信我,你会很开心的。
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] = '\0';
buffer_length--;
}
buffer_counter++;
} // end while