После добавления необходимых включений <stdio.h>
и <stdlib.h>
мы можем запустить код под Valgrind, чтобы увидеть, что не так:
valgrind -q --leak-check=full ./52626203
==1409== Invalid write of size 8
==1409== at 0x10919F: update (52626203.c:16)
==1409== by 0x109209: main (52626203.c:28)
==1409== Address 0x4a39050 is 0 bytes after a block of size 16 alloc'd
==1409== at 0x48357BF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1409== by 0x10915A: update (52626203.c:12)
==1409== by 0x109209: main (52626203.c:28)
==1409==
==1409== Invalid write of size 8
==1409== at 0x1091B6: update (52626203.c:17)
==1409== by 0x109209: main (52626203.c:28)
==1409== Address 0x4a39058 is 8 bytes after a block of size 16 alloc'd
==1409== at 0x48357BF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1409== by 0x10915A: update (52626203.c:12)
==1409== by 0x109209: main (52626203.c:28)
==1409==
==1409== Invalid read of size 8
==1409== at 0x1091C6: update (52626203.c:19)
==1409== by 0x109209: main (52626203.c:28)
==1409== Address 0x4a39058 is 8 bytes after a block of size 16 alloc'd
==1409== at 0x48357BF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1409== by 0x10915A: update (52626203.c:12)
==1409== by 0x109209: main (52626203.c:28)
==1409==
5.000000 10.000000 4.000000
==1409== Invalid read of size 8
==1409== at 0x109212: main (52626203.c:30)
==1409== Address 0x4a39058 is 8 bytes after a block of size 16 alloc'd
==1409== at 0x48357BF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1409== by 0x10915A: update (52626203.c:12)
==1409== by 0x109209: main (52626203.c:28)
==1409==
5.000000 10.000000 4.000000
==1409== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1409== at 0x48357BF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1409== by 0x10915A: update (52626203.c:12)
==1409== by 0x109209: main (52626203.c:28)
==1409==
Это показывает нам, что это попытка присвоить struct1->a[1][0]
это ошибка, предполагая, что мы выделили только достаточно места для a[0]
, а не a[1]
.
Это приводит нас прямо к строке выделения, где мы видим, что пропустили разыменование в аргументе sizeof
.Это должно быть
struct1->a = malloc(2 * sizeof *struct1->a);
// ^
Мы выделяли место для двух указателей на двойной массив, а не достаточно для двух двойных массивов по два элемента в каждом.
Кстати, в реальном коде нетне забудьте проверить указатель, возвращенный из malloc()
, прежде чем пытаться его использовать, и free()
, когда закончите.