1

Malloc returns a null when heap memory is insufficient OR when heap is super fragmented.

What I would like to know is that if there are OTHER circumstances when malloc() returns a NULL?

PS:Under what circumstances can malloc return NULL? didn't seem to answer my question

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
Leon
  • 346
  • 3
  • 15
  • 1
    Probably when you pass a size of 0 aswell. – Fredrik Jan 21 '20 at 22:59
  • I see it may return a null or an actual address(based on what comments from other answered mentioned) – Leon Jan 21 '20 at 23:05
  • It's not clear what your question is. `malloc()` either returns a valid pointer, or it returns NULL. If it returns NULL, your program needs to do something appropriate, like print an error message and exit. – user3386109 Jan 21 '20 at 23:06
  • There are many, many, many systems and implementations. From the link the second answer says: `the very definition of memory exhaustion is malloc not giving you the desired space`. Malloc returns NULL when there is no memory. You can now reason _why_ is there no memory - because it's "super fragmented" or it's too small, or for any other reason (and there are many reasons), but then specify what implementation of malloc and operating system you exactly have in mind. Because right now I think the question is too broad. – KamilCuk Jan 21 '20 at 23:06
  • I see, the reason I'm being downvoted is because there are too many reasons to why memory might be insufficient. – Leon Jan 21 '20 at 23:10

2 Answers2

4

When does malloc() in C return NULL?

malloc() returns a null pointer when it fails to allocate the needed space.

This can be due to:

  1. Out-of-memory in the machine (not enough bytes)
  2. Out-of-memory for the process (OS may limit space per process)
  3. Out of memory handles (Too many allocations, some allocators has this limit)
  4. Too fragmented (Enough memory exist, but allocator can't/does not want to re-organize into a continuous block).
  5. All sorts of reasons like your process is not worthy of more.

malloc(0) may return a null pointer. C17/18 adds a bit.

If the size of the space requested is zero, the behavior is implementation-defined:
either a null pointer is returned to indicate an error,
or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.

malloc(0) may return a null pointer. (pre-C17/18)

If the size of the space requested is zero, the behavior is implementation-defined:
either a null pointer is returned,
or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.

The "to indicate an error" of C17/18 implies to me that a null pointer return is an error, perhaps due to one of the above 5 reasons and a non-erroring malloc(0) does not return a null pointer.

I see this as a trend to have p = malloc(n); if (p==NULL) error(); to always be true on error even if n is 0. Else one might code as if (p==NULL && n > 0) error();

If code wants to tolerate an allocation of zero to return NULL as a non-error, better to form a helper function to test for n == 0 and return NULL than call malloc().


Conversely a return of non-null pointer does not always mean this is enough memory. See Why is malloc not “using up” the memory on my computer?

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Sorry newbie in C here. What are memory handles and what is meant by point number 2? – Leon Jan 21 '20 at 23:52
  • @leon Consider an allocation system that allowed only 1,000,000 allocations (handles) regardless of the sum of their sizes. Too many small allocations would chew up the handles. The details of a memory allocator are implementation dependant and another allocator might not have a "handle" limitation at all. – chux - Reinstate Monica Jan 21 '20 at 23:55
  • @Leon An OS may limit each process/program to a max memory usage, say 2 Gbytes, even if there was 64 Gbytes of memory - again an implementation detail. C does **not** specify details of how an allocator must work. – chux - Reinstate Monica Jan 21 '20 at 23:58
  • Am I then correct to say that 1,000,000 allocations will only be allowed assuming program has yet to exceed the max memory usage of, say 2 GB? – Leon Jan 22 '20 at 00:20
  • @Leon, Yes - again an allocater may or may not have a handle limit. But if it did, the handles could run out before the memory pool is empty. – chux - Reinstate Monica Jan 22 '20 at 01:11
1

If for some reason, the memory that you ask to malloc can't be allocated or sometimes if you ask for 0 memory, it returns NULL.

Check the documentation

Alberto Sinigaglia
  • 12,097
  • 2
  • 20
  • 48
  • 3
    `or you ask for 0 memory, it returns null` for 0, it is implementation defined. It may return NULL for 0. It may return a pointer that can later be passed to `free`. – KamilCuk Jan 21 '20 at 23:00
  • `malloc(0)` doesn't always return `null`. – Joshua Yonathan Jan 21 '20 at 23:01
  • @KamilCuk Either way, the pointer can be passed to `free`, it's just that you can only use the non-`NULL` one. – Thomas Jager Jan 21 '20 at 23:06
  • Just to be picky, `NULL` is also a pointer that can later be passed to `free`. (`free(NULL)` is defined to do nothing.) It's implementation-defined whether `malloc(0)` returns a null pointer (that can be passed to `free`) or a non-null pointer that can be passed to `free`. – Keith Thompson Jan 21 '20 at 23:14
  • sorry, added the "sometimes" as reported to the documentation – Alberto Sinigaglia Jan 22 '20 at 11:27