SegFault

How much memory requires malloc(0) ?

Why doing nothing is inefficient.

January 30 , 2018

At first glance, the answer seems clear: A request to allocate no memory should not require any memory at all. However, you can easily exhaust all available memory without ever allocating more than zero bytes. But before we take a look at malloc(0) lets first check the simpler case of malloc(1).

People new to C/C++ often ask a similar question:
How can I get the size of a memory block a pointer points to ?
A common answer to this question is, that it's not possible. However, when I call free at the pointer, it nows like magic how much memory was allocated and frees it correctly. So it has to be stored somewhere. That somewhere in most of the cases is a structure directly preceeding the returned pointer. In the case of dlmalloc this structure consists of a variable of type size_t, which contains the memory blocks size and some flags. In addition to the size of this current block, it also stores the size of the block directly in front of it.

In case a block is not in use dlmalloc also stores pointers to the previous free block as well as the next free block. If you take this into consideration, you end up with a minimum block size of 32 bytes. This means that malloc(1) in really allocates 32 bytes of memory. The following program allocates a byte and then outputs the size of the block, which unsurprisingly is 32 (or more).

#include <iostream>
#include <cstdlib>
int main() {
	size_t* ptr = (size_t*)malloc(1);
	std::cout << (ptr[-1] & ~0x1) << std::endl;
}

Now that we took a look at the simple case, we can take a look at malloc(0). If you read the C standard you might be surprised to find out that malloc is allowed to return NULL if the size was zero. It does not say whether NULL or a valid pointer will be returned. Most programs, however, treat it as an error if malloc returns NULL, most C libraries will instead return a valid memory block of minimum size, which as we found out is 32 bytes. The correct way to check for errors after malloc would be the following:

void* ptr = malloc(size);
if(ptr == NULL && size != 0) { /* Error */ }

So the answer to this question is: It requires 32 bytes of memory to allocate no memory.