Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Valgrind错误,尺寸和尺寸的读取无效;条件跳转或移动取决于未初始化的值_C_Valgrind - Fatal编程技术网

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