country = realloc(country, countries_capacity);
Вы, похоже, полагаетесь на realloc(0, new_size)
, чтобы вести себя как malloc(new_size)
. Это нормально, но тогда вы должны убедиться, что переменная-указатель, переданная в 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)
Они оба вызваны реальными ошибками: во-первых, массив line
никогда не превращается в правильную C-строку (путем добавления нулевого терминатора), во-вторых, потому что size передан к realloc
это неправильно. Вам нужно
line[line_ix] = '\0';
сразу после цикла while
и
country = realloc(country, countries_capacity * sizeof(Data));
вместо realloc
звонка, который у вас есть сейчас.
С этими изменениями я не получаю никаких жалоб. У вас все еще есть проблема, которую вы используете sscanf
, что всегда плохая идея , но valgrind не может помочь вам с этим.