Hi,
I've written a small program which finds saddle points on an energy surface and I am trying to get the memory management correct. I'm always messing this up.
The code works, and I've use valgrind to debug.
I get the strange result that for 100 iterations there seems to be no problem:
==15583== Memcheck, a memory error detector
==15583== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==15583== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==15583== Command: ./test -wn 100
==15583==
==15583== Invalid read of size 8
==15583== at 0x403AB1: void grow2d<gauss>(gauss**&, unsigned long&, int) (test.cpp:142)
==15583== by 0x4029A9: main (test.cpp:236)
==15583== Address 0x5937050 is 0 bytes after a block of size 16 alloc'd
==15583== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15583== by 0x40254E: main (test.cpp:153)
==15583==
==15583== Invalid read of size 8
==15583== at 0x403B78: void grow2d<double>(double**&, unsigned long&, int) (test.cpp:142)
==15583== by 0x402C4B: main (test.cpp:255)
==15583== Address 0x59370a0 is 0 bytes after a block of size 16 alloc'd
==15583== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15583== by 0x40256C: main (test.cpp:154)
==15583==
==15583==
==15583== HEAP SUMMARY:
==15583== in use at exit: 0 bytes in 0 blocks
==15583== total heap usage: 9,775 allocs, 9,775 frees, 179,838 bytes allocated
==15583==
==15583== All heap blocks were freed -- no leaks are possible
==15583==
==15583== For counts of detected and suppressed errors, rerun with: -v
==15583== ERROR SUMMARY: 28 errors from 2 contexts (suppressed: 4 from 4) |
While for 1000 iterations, I get the following messages
==15596== Memcheck, a memory error detector
==15596== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==15596== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==15596== Command: ./test -wn 1000
==15596==
==15596== Invalid read of size 8
==15596== at 0x403AB1: void grow2d<gauss>(gauss**&, unsigned long&, int) (test.cpp:142)
==15596== by 0x4029A9: main (test.cpp:236)
==15596== Address 0x5937050 is 0 bytes after a block of size 16 alloc'd
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x40254E: main (test.cpp:153)
==15596==
==15596== Invalid read of size 8
==15596== at 0x403B78: void grow2d<double>(double**&, unsigned long&, int) (test.cpp:142)
==15596== by 0x402C4B: main (test.cpp:255)
==15596== Address 0x59370a0 is 0 bytes after a block of size 16 alloc'd
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x40256C: main (test.cpp:154)
==15596==
==15596==
==15596== HEAP SUMMARY:
==15596== in use at exit: 2,120 bytes in 79 blocks
==15596== total heap usage: 83,875 allocs, 83,796 frees, 1,365,438 bytes allocated
==15596==
==15596== 76 bytes in 1 blocks are definitely lost in loss record 1 of 13
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x402D88: main (test.cpp:265)
==15596==
==15596== 76 bytes in 1 blocks are definitely lost in loss record 2 of 13
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x402DA0: main (test.cpp:266)
==15596==
==15596== 80 bytes in 5 blocks are indirectly lost in loss record 3 of 13
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x4029F7: main (test.cpp:239)
==15596==
==15596== 80 bytes in 5 blocks are indirectly lost in loss record 4 of 13
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x402A13: main (test.cpp:240)
==15596==
==15596== 120 bytes in 5 blocks are indirectly lost in loss record 5 of 13
==15596== at 0x4C24DFA: operator new(unsigned long) (vg_replace_malloc.c:261)
==15596== by 0x4029C8: main (test.cpp:237)
==15596==
==15596== 152 bytes in 1 blocks are definitely lost in loss record 6 of 13
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x402DB8: main (test.cpp:267)
==15596==
==15596== 304 bytes in 19 blocks are indirectly lost in loss record 7 of 13
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x402C71: main (test.cpp:256)
==15596==
==15596== 304 bytes in 19 blocks are indirectly lost in loss record 8 of 13
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x402E81: main (test.cpp:274)
==15596==
==15596== 304 bytes in 19 blocks are indirectly lost in loss record 9 of 13
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x402EAD: main (test.cpp:275)
==15596==
==15596== 344 (64 direct, 280 indirect) bytes in 1 blocks are definitely lost in loss record 10 of 13
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x403A82: void grow2d<gauss>(gauss**&, unsigned long&, int) (test.cpp:141)
==15596== by 0x4029A9: main (test.cpp:236)
==15596==
==15596== 456 (152 direct, 304 indirect) bytes in 1 blocks are definitely lost in loss record 11 of 13
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x402DD0: main (test.cpp:268)
==15596==
==15596== 456 (152 direct, 304 indirect) bytes in 1 blocks are definitely lost in loss record 12 of 13
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x402DE8: main (test.cpp:269)
==15596==
==15596== 560 (256 direct, 304 indirect) bytes in 1 blocks are definitely lost in loss record 13 of 13
==15596== at 0x4C24A72: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15596== by 0x403B49: void grow2d<double>(double**&, unsigned long&, int) (test.cpp:141)
==15596== by 0x402C4B: main (test.cpp:255)
==15596==
==15596== LEAK SUMMARY:
==15596== definitely lost: 928 bytes in 7 blocks
==15596== indirectly lost: 1,192 bytes in 72 blocks
==15596== possibly lost: 0 bytes in 0 blocks
==15596== still reachable: 0 bytes in 0 blocks
==15596== suppressed: 0 bytes in 0 blocks
==15596==
==15596== For counts of detected and suppressed errors, rerun with: -v
==15596== ERROR SUMMARY: 35 errors from 9 contexts (suppressed: 4 from 4) |
Since the source is too large to post here (~300 lines) I've put it here:
http://petveturas.com/tmp/neb.cpp
From the valgrind output there seem to be at least two problems, (1) I'm apparently reading/writing to something of size 0 and (2) at some point memory is allocated which is not freed.
The problematic part seems to be the compute function (line 62) because if comment it out the 'leak' errors disappear but I don't allocate anything dynamically there so I don't understand why it's not destroyed outside the scope, the references are also not resized.
Another part where I'm really uncertain is the function grow2d (line 138), perhaps the real problem is there.
I initially wrote it as:
1 2
|
size_t size = 2*n+1;
type** newlist = new type*[size];
|
1 2
|
size_t size = 2*n+1;
type** newlist = new type*[size+1];
|
But the +1 seems necessary..
Sorry for the long code, but I'm not sure how to reduce it to a minimal example.
I hope somebody can give some hints/advice on what I'm doing wrong here.
Thanks in advance!
Jaap