Question

I've got the following code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char ** argv)
{
    //just checking to see where the stack 
    printf("The stack is around %p\n", &argc); is, making sure arr isn't in it
    char ** arr = malloc(8*sizeof(char*));
    printf("arr is size %li, at %p\n", sizeof(arr), arr);
    arr = realloc(arr, 100); //I picked a weird number to show it isn't doing anything. I've picked different numbers (like 200, 2*sizeof(char*)*sizeof(arr), and 16)
    printf("arr is size %li, at %p\n", sizeof(arr), arr);
}

That's the entirety of the file (it's a unit test; I was noticing it elsewhere)

The output of the above is as follows:

The stack is around 0x7fff5b94d12c
arr is size 8, at 0x120f010
arr is size 8, at 0x120f010

Perhaps I'm misunderstanding what realloc should do. I'm expecting the following output.

The stack is around 0x7fff5b94d12c
arr is size 8, at 0x120f010
arr is size <size>, at <somewhere>

where <size> is... something odd like 12... at least not 8 and <somewhere> is most likely 0x120f010 but possibly anywhere reasonable.

Are my expectations wrong or am I using realloc incorrectly?

Was it helpful?

Solution

The output of your program is correct, because

  • Neither malloc nor realloc have anything to do with the automatic storage (i.e. "the stack"). They allocate memory from the dynamic storage area (i.e. "the heap"). One should not expect the position of the top of the stack to change in response to calls to malloc, realloc, or for that matter, any other function.
  • The value of sizeof(arr) does not depend on what you have allocated to it. It is computed at compile time, and it is always equal to the size of a pointer. On your system, pointers use 8 bytes.
  • malloc often gives you more memory that you ask, and stores the actual value in a special location that realloc can access at a later time. If you realloc down, or realloc within the bounds, the value returned by realloc does not change. That's the reason why it may perform better than simply calling malloc and memcpy.

OTHER TIPS

sizeof arr

That's the same as

sizeof char**

The size of a pointer isn't going to change, and taking the size of a pointer is not going to tell you how much memory it refers to. Pointers are not arrays, and sizeof is evaluated at compile time.

As for the address bit, realloc doesn't guarantee that the memory block was moved. It could simply expand it successfully and return the same address.

Also, I realize this is just example code, but be aware that, if realloc failed, you leaked what arr originally pointed to.

It's not uncommon, and in fact a bit expected, that a malloc call followed directly by realloc would not change the address of the pointer. In many cases the allocator can just extend the amount of memory reserved at the address and not have to move the pointer. This is what is happening here.

This isn't something you should ever depend on though. It's just a quirk of the implementation

If your assumption is that realloc() has to return a different pointer, then your assumption is wrong.

Typically if you're reducing the size of the allocated memory or leaving it "as is", then realloc() can return the same pointer and avoid copying data, etc.

Sometimes if you're increasing the size of the allocated memory realloc() can check if there's free space above the existing space and still return the same pointer (and avoid copying data).

Mostly, it's only when there is no free space above the allocated memory that realloc() must copy the data somewhere else and return a different pointer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top