Reallocation of memory to empty reference

Viewed 71

I was watching a lesson on malloc and while they were doing a specific example, it made no sense for why such code to print out the entire pointer.

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

int main(void) {
    
    int *list = malloc(3 * sizeof(int));
    
    if (list == NULL)
        return 1;
        
    list[0] = 1;
    list[1] = 2;
    list[2] = 3;
    
    int *tmp = malloc(4 * sizeof(int));
    
    if (tmp == NULL)
        return 1;
        
    for (int i = 0; i < 3; i++)
        tmp[i] = list[i];
        
    tmp[3] = 4;
    
    free(list);

    //From this line and below is the thing in question.
    list = tmp;
    
    for (int i = 0; i < 4; i++)
        printf("%i\n", list[i]);
}

OUTPUT:

~/test/ $ ./malloc_test
1
2
3
4

From my understanding of free(), it de-allocates the memory allocated by allocation functions and free() will 'free' up the memory of the pointer.

If I were to go by this definition:

  1. *list was allocated 12 bytes (3 * sizeof(int), sizeof(int) = 4
  2. Hard code list with numbers
  3. *tmp was allocated 16 bytes
  4. Copy the numbers in list to tmp
  5. Free up list making it have no allocated bytes
  6. List is now equal to tmp
  • How can list now be equal to tmp when list doesn't have any allocated memory?

  • Is list pointing to the address of tmp? If yes, why do we need to not allocate memory for list since earlier in the code, we did this int *tmp = malloc(4 * sizeof(int));

3 Answers

*list was allocated 12 bytes (3 * sizeof(int), sizeof(int) = 4

To be precise, you allocated 12 bytes of memory and set list to point to that memory.

Hard code list with numbers
*tmp was allocated 16 bytes

Again, to be precise, you allocated 16 bytes of memory and set the pointer variable tmp to point to it.

Copy the numbers in list to tmp
Free up list making it have no allocated bytes

To be precise, you freed the object that list pointed to so now list points to garbage and must not be dereferenced.

list is now equal to tmp

To be precise, list now points to the same thing tmp points to, those 16 bytes you allocated that previous was pointed to only by tmp.

How can list now be equal to tmp when list doesn't have any allocated memory?

Previously, list didn't point to allocated memory. But you changed it to point to the 16 bytes you allocated second. The value of a pointer is what it points to, list and tmp now point to the same thing so they have the same value. So they're now equal.

Is list pointing to the address of tmp? If yes, why do we need to not allocate memory for list since earlier in the code, we did this int *tmp = malloc(4 * sizeof(int));

The code frees the first allocated block of memory. If it didn't allocate a second block of memory, there would be nothing valid for either pointer to point to!

When you copy a pointer you're just copying the pointer's value1:

list = tmp;

This means that list now contains a copy of the tmp pointer, or in other words, they both point to the same memory address. In this case that address is an allocation.

Once they're made identical you can reference either of them interchangeably.


1 Of course this presumes the pointers are of the same type, like int* to int*, and not int to int**. You could also assign to void* and convert back again later, that works as well.

a pointer is a data type that is only assigned memory addresses of the corresponding data type, in your case in list = tmp; you assign the first position of that memory block that you created with int * tmp = malloc (4 * sizeof (int)); , when you make the assignment to list it will point to that memory address. (in your case at the beginning of that memory block).

Related