Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.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 条件跳转或移动取决于单位化值_C_Memory_Valgrind - Fatal编程技术网

C 条件跳转或移动取决于单位化值

C 条件跳转或移动取决于单位化值,c,memory,valgrind,C,Memory,Valgrind,valgrind给了我这个错误,我用--track origins=yes运行它,找到了错误所在的行,但我不知道错误是什么,也不知道如何修复它 #include <stdio.h> #include <stdlib.h> typedef struct Date{ int year; int month; int day; } Date; typedef struct Data{ Date date; float temp;

valgrind给了我这个错误,我用--track origins=yes运行它,找到了错误所在的行,但我不知道错误是什么,也不知道如何修复它

#include <stdio.h>
#include <stdlib.h>

typedef struct Date{
    int year;
    int month;
    int day;
} Date;

typedef struct Data{
    Date date;
    float temp;
    float uncertainty;
    char country[100];
} Data;

int main(){
    FILE* f = fopen("tempcountries_short.csv", "r");
    char* line = NULL;
    int capacity = 0;
    int countries_capacity = 0;
    int line_ix = 0;
    char c;
    Data* country = NULL;
    while ((c = fgetc(f)) != '\n'){ 
        if (line_ix + 1 > capacity){
            if (capacity == 0)                    
                capacity = 10;
            else
                capacity = capacity * 2;
            line = realloc(line, capacity); 
        }
        line[line_ix] = c;
        line_ix++;
    }
    if (countries_capacity == 0)
        countries_capacity = 10;
    else
        countries_capacity = countries_capacity * 2;
    country = realloc(country, countries_capacity);
    printf("%i\n",sscanf(line, "%i - %i - %i, %f , %f , %s", 
           &country->date.year, &country->date.month,
           &country->date.day, &country->temp, &country->uncertainty,
           country->country));
}
#包括
#包括
类型定义结构日期{
国际年;
整月;
国际日;
}日期;
typedef结构数据{
日期;
浮子温度;
浮动不确定性;
查尔国家[100];
}数据;
int main(){
文件*f=fopen(“temp_short.csv”,“r”);
char*line=NULL;
int容量=0;
国际单位容量=0;
int line_ix=0;
字符c;
数据*国家=空;
而((c=fgetc(f))!='\n'){
如果(第九行+1>容量){
如果(容量==0)
容量=10;
其他的
容量=容量*2;
线路=realloc(线路,容量);
}
行[line_ix]=c;
行_ix++;
}
如果(国家/地区容量==0)
国家/地区能力=10;
其他的
国家/地区容量=国家/地区容量*2;
国家=realloc(国家,国家/地区容量);
printf(“%i\n”,sscanf(行“%i-%i-%i,%f,%s”,
&国家->日期.年,&国家->日期.月,
&国家->日期、日期和国家->温度和国家->不确定性,
国家->国家);
}
这是Valgrind的输出,带有选项--leak check=full和--track origins=yes:正如您所看到的,还有许多其他错误,我也不明白是什么导致了这些错误

程序从一个文件中读取关于许多国家温度的数据行,我只是从单个国家的代码部分复制错误,但是国家应该是一个由许多数据结构组成的数组。下面是我正在阅读的文件中的一行示例:

1972-03-01,4.787,0.342,斯洛伐克问题在于:

country = realloc(country, countries_capacity);
country
尚未初始化,它包含一个不确定的值

声明如下时,只需将
country
初始化为
NULL

Data* country = NULL;
问题在于:

country = realloc(country, countries_capacity);
country
尚未初始化,它包含一个不确定的值

声明如下时,只需将
country
初始化为
NULL

Data* country = NULL;
您似乎依赖于
realloc(0,新大小)
作为
malloc(新大小)
。这很好,但是您必须确保传递给
realloc
的指针变量确实为空。在此点之前没有代码初始化
country
变量,并且在其声明中

Data* country;
。。。没有初始值设定项。将此更改为

Data *country = 0;
这部分问题应该解决

通常,当您从
valgrind
中得到一整串错误时,只有第一个错误是有意义的,因此请查看这是否解决了所有问题


编辑:对于上面已更正的程序版本,输入显示的样本行,我没有收到任何关于
realloc
中未初始化值的投诉,但我仍然收到关于
sscanf
中未初始化值的投诉:

==28542== Conditional jump or move depends on uninitialised value(s)
==28542==    at 0x4C340E6: rawmemchr (vg_replace_strmem.c:1409)
==28542==    by 0x4EB6291: _IO_str_init_static_internal (strops.c:41)
==28542==    by 0x4EA476C: __isoc99_vsscanf (isoc99_vsscanf.c:41)
==28542==    by 0x4EA46D3: __isoc99_sscanf (isoc99_sscanf.c:31)
==28542==    by 0x108886: main (in /tmp/a.out)
以及关于无效写入的投诉:

==28542== Invalid write of size 4
==28542==    at 0x4E98FFB: _IO_vfscanf (vfscanf.c:1898)
==28542==    by 0x4EA4781: __isoc99_vsscanf (isoc99_vsscanf.c:43)
==28542==    by 0x4EA46D3: __isoc99_sscanf (isoc99_sscanf.c:31)
==28542==    by 0x108886: main (in /tmp/a.out)
==28542==  Address 0x51f41a8 is 8 bytes inside a block of size 10 alloc'd
==28542==    at 0x4C2CABF: malloc (vg_replace_malloc.c:298)
==28542==    by 0x4C2EE04: realloc (vg_replace_malloc.c:785)
==28542==    by 0x10883C: main (in /tmp/a.out)
这两个都是由真正的bug引起的:第一个是因为
数组从来没有被制作成正确的C字符串(通过添加nul终止符),第二个是因为传递给
realloc
的大小是错误的。你需要

line[line_ix] = '\0';
紧跟在
while
循环之后,以及

country = realloc(country, countries_capacity * sizeof(Data));
而不是现在的
realloc
呼叫


有了这些变化,我没有收到任何抱怨。您仍然存在使用
sscanf
的问题,也就是说,但是valgrind无法帮助您解决这个问题

您似乎依赖于
realloc(0,新大小)
作为
malloc(新大小)
。这很好,但是您必须确保传递给
realloc
的指针变量确实为空。在此点之前没有代码初始化
country
变量,并且在其声明中

Data* country;
。。。没有初始值设定项。将此更改为

Data *country = 0;
这部分问题应该解决

通常,当您从
valgrind
中得到一整串错误时,只有第一个错误是有意义的,因此请查看这是否解决了所有问题


编辑:对于上面已更正的程序版本,输入显示的样本行,我没有收到任何关于
realloc
中未初始化值的投诉,但我仍然收到关于
sscanf
中未初始化值的投诉:

==28542== Conditional jump or move depends on uninitialised value(s)
==28542==    at 0x4C340E6: rawmemchr (vg_replace_strmem.c:1409)
==28542==    by 0x4EB6291: _IO_str_init_static_internal (strops.c:41)
==28542==    by 0x4EA476C: __isoc99_vsscanf (isoc99_vsscanf.c:41)
==28542==    by 0x4EA46D3: __isoc99_sscanf (isoc99_sscanf.c:31)
==28542==    by 0x108886: main (in /tmp/a.out)
以及关于无效写入的投诉:

==28542== Invalid write of size 4
==28542==    at 0x4E98FFB: _IO_vfscanf (vfscanf.c:1898)
==28542==    by 0x4EA4781: __isoc99_vsscanf (isoc99_vsscanf.c:43)
==28542==    by 0x4EA46D3: __isoc99_sscanf (isoc99_sscanf.c:31)
==28542==    by 0x108886: main (in /tmp/a.out)
==28542==  Address 0x51f41a8 is 8 bytes inside a block of size 10 alloc'd
==28542==    at 0x4C2CABF: malloc (vg_replace_malloc.c:298)
==28542==    by 0x4C2EE04: realloc (vg_replace_malloc.c:785)
==28542==    by 0x10883C: main (in /tmp/a.out)
这两个都是由真正的bug引起的:第一个是因为
数组从来没有被制作成正确的C字符串(通过添加nul终止符),第二个是因为传递给
realloc
的大小是错误的。你需要

line[line_ix] = '\0';
紧跟在
while
循环之后,以及

country = realloc(country, countries_capacity * sizeof(Data));
而不是现在的
realloc
呼叫



有了这些变化,我没有收到任何抱怨。您仍然存在使用sscanf的问题,也就是说,但是valgrind不能帮助您解决这个问题。

行的最后一个字符必须设置为\0,才能成为正确的空终止字符串。

行的最后一个字符必须设置为\0,才能成为正确的空终止字符串。

为什么不使用bzero而不是=null或=0?这是完全一样的吗?事实上,这是我在复制代码以限制错误时犯的一个错误,在原始版本中,我将初始化设置为NULL。我只是换了一个,然后再次运行Valgrind,它没有解决任何问题。另外,你给出的链接说scanf是个坏主意,而不是sscanf。剩下的valgrind投诉请参见编辑。关于scanf,链接中页面上描述的scanf的所有缺陷都同样适用于sscanf(是的,我知道该页面的作者不这么认为)。@AntoninGavrel
bzero
已被弃用,一个