I have a function that, when called, takes a struct Pieces* field from a struct Torrent and initializes it according to the information contained in a char array.
Here is what the function call looks like (metadata.c:230):
get_pieces(t.pieces, &t.num_pieces, data);
In the get_pieces() function, I initialize t.pieces, like so (metadata.c:65):
pieces = calloc(*num_pieces, sizeof(struct Piece));
However, when I run valgrind, it says:
==8701== 76,776 bytes in 1 blocks are definitely lost in loss record 634 of 634
==8701== at 0x4C28349: calloc (vg_replace_malloc.c:467)
==8701== by 0x4025A4: get_pieces (metadata.c:65)
==8701== by 0x402CDB: init_torrent (metadata.c:230)
==8701== by 0x404018: start_torrent (torrent.c:35)
==8701== by 0x40232E: main (main.c:17)
even though a pointer, t->pieces, is still available when my program terminates and can be free’d. Why does this leak memory?
The full source code is available at https://github.com/robertseaton/slug.
This leaks memory because your
get_piecesfunction is passing in a pointer to Pieces:You then allocate memory to
piecesinside of this method. When it returns, that allocated memory is no longer accessible by anything.This is because your pointer is passed by value – reassigning the pointer does not change the calling function’s copy. In order to affect that calling function, you’d have to pass a pointer to the pointer, so you can assign the original copy correctly:
And, at the call site, pass in the address to the pointer.