After adding the necessary includes of <stdio.h>
and <stdlib.h>
, we can run the code under Valgrind to see what's wrong:
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==
This shows us that it's the attempt to assign to struct1->a[1][0]
that's at fault, suggesting that we allocated only enough space for a[0]
and not also a[1]
.
That takes us right to the allocation line, where we see we missed a dereference in the argument to sizeof
. It should be
struct1->a = malloc(2 * sizeof *struct1->a);
// ^
We were allocating space for two pointers to double array, rather than enough for two double arrays of two elements each.
BTW, in real code, don't forget to check the pointer returned from malloc()
before you try to use it, and to free()
it when you're done.