2

Let's say we run this piece of code in isolation:

malloc(1024);

Will this result in a memory leak, or will C automatically know to free a pointer with no references?

In other words, can I avoid having to assign it to a pointer?

void *p = malloc(1024);
free(p);
oink
  • 1,443
  • 2
  • 14
  • 23
  • What you're talking about is called a *garbage collector*. C (usually) has no such feature. The rule here is simple: if an each call to malloc() (and other *alloc() functions) is matched by exacly one call to free(), then there are no leaks. – HolyBlackCat Jul 15 '16 at 23:16
  • 1
    If you don't assign the result of `malloc()` to a variable, how do you access the allocated memory? – Keith Thompson Jul 15 '16 at 23:26
  • Put another way, why do you want to allocate 1,024 bytes of memory if you're not going to use it? – Crowman Jul 16 '16 at 00:11
  • The actual application is where I'm nesting several function calls that each return new pointers. Like `bignum *add(bignum *a, bignum *b)`. – oink Jul 16 '16 at 01:53
  • @cchan3141 declare the parameters like `const bignum* const a` and don't change them in the function, then frees are up to the caller – cat Oct 21 '16 at 12:35
  • @cchan3141 alternatively declare your function `void add (bignum* const a, const bignum* const b)` and modify a – cat Oct 21 '16 at 12:36

2 Answers2

5

It's a memory leak. C does absolutely no memory management for you (except for the C compiler allocating stack space for variables).

Jashaszun
  • 9,207
  • 3
  • 29
  • 57
5

In any code you write which dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed. Freeing the memory is up to you.

If you assign a new block of memory to a pointer that currently points to an existing block of memory without first freeing the block, you have just overwritten the starting address for the original block of memory held by the pointer (violating rule 1 above) and you have now lost the ability to free the original block -- which is your memory leak.

royhowie
  • 11,075
  • 14
  • 50
  • 67
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Thank you for the very clear explanation. The original application was a bunch of nested function calls each returning new pointers, and it seems I must make sure I save the pointer somewhere first before calling each next function. – oink Jul 15 '16 at 23:21
  • @David could you please give me an explanation to my [Question](https://stackoverflow.com/questions/33412495/why-doesnt-valgrind-spot-the-leak-when-program-was-compiled-with-gcc-5-2-0)? – Michi Jul 16 '16 at 02:23
  • Sure, but it looks like you got it sorted. My guess would be you `-O2` optimization optimized out the non-use of the allocation resulting in the `0 bytes allocated` message from `valgrind`? Looks like you have an answer now. If you have further questions, just ask. – David C. Rankin Jul 16 '16 at 02:27
  • I'm still not ok, because the answer and the comments are not showing some reference where I can check if that's true, even if maybe are the right one. Things like use -O0 instead of -O2 doesn't explain Why the leak is not spotted – Michi Jul 16 '16 at 02:35
  • OK, let me finish dishes, etc.. and I'll take a closer look. The initial look I took showed `valgrind` reporting `0 bytes allocated` with 5.2, meaning there would be no report of a leak (even if you have code to produce a leak) because there was no memory allocated to begin with -- therefore there can be no leak to report. The differences in the reporting would generally have to do with what was/wasn't optimized out by the compiler. If you never use the memory you allocate, the compiler can just never allocate it to begin with and optimize all that code out. (let me look closer) – David C. Rankin Jul 16 '16 at 02:56