2

I'm very new in C programming and I was playing around with malloc(), free() and Pointer Assignment in order to get a better grasp of it.

Here is my code:

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

#define SIZE    10

void
array_fill(int * const arr, size_t n)
{
    size_t i;
    for (i = 0; i < n; i++)
    arr[i] = i;
}

void
array_print(const int * const arr, size_t n)
{
    size_t i;
    for (i = 0; i < n; i++)
    printf("%d ", arr[i]);

    printf("\n");
}


int
main(int argc, char ** argv)
{
    int * p1, * p2;

    p1 = (int *) malloc(SIZE * sizeof(int));
    p2 = p1;

    array_fill(p1, SIZE);
    array_print(p1, SIZE);
    array_print(p2, SIZE);

    printf("\nFREE(p1)\n");
    free(p1);

    array_print(p2, SIZE);

    return (0);
}

Compiling it with gcc test.c -o test and running it with ./test:

0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 

FREE(p1)
0 0 2 3 4 5 6 7 8 9
  1. p2 = p1, does it mean that p2 points to the same value as p1?
  2. After freeing p1 why I can still print p2 (Value of index 1 is different)? Am I causing any memory leak or pointer dangling?
  3. Is this normal to be able to print p2 even p1 is freed?
Duck
  • 26,924
  • 5
  • 64
  • 92
user3727663
  • 23
  • 1
  • 3
  • 1
    Possible duplicate: [How are we able to access the pointer after deallocating the memory?](http://stackoverflow.com/questions/22033822/how-are-we-able-to-access-the-pointer-after-deallocating-the-memory) – Paul R Jun 10 '14 at 21:02

4 Answers4

3

1) Yes

2) You are accessing freed memory which is a bad thing.

3) The behaviour is undefined. It could work, it could crash, it could print garbage, it could suck us all into a black hole (though unlikely)

DrC
  • 7,528
  • 1
  • 22
  • 37
  • Thanks for your answer. Is there a way to make the `p2` automatically points to `NULL` after setting `p1` to `NULL`? – user3727663 Jun 10 '14 at 21:27
  • Not that I know of. Common practice is to invalidate the pointer by setting to NULL after the free but that doesn't help much here as the pointer variable passed to free is not the issue. – DrC Jun 10 '14 at 23:41
3

p2 = p1, does it mean that p2 points to the same value as p1?

Yes, after the assignment both pointers point to the same region of memory.

After freeing p1 why I can still print p2 (Value of index 1 is different)? Am I causing any memory leak or pointer dangling?

Yes, once you free p1, the p2 pointer becomes dangling. Accessing anything through it is undefined behavior.

Is this normal to be able to print p2 even p1 is freed?

No, it is undefined behavior.

Don't let the fact that you see numbers that look like ones that you have previously confuse you: any resemblance with the numbers that were there before you called free is a complete coincidence. Unfortunately, coincidences like that make problems with dangling pointers extremely hard to find. To aid with this problem, memory profiler programs take over the free-d region, and deliberately write some garbage values into it. This makes detection faster, but it is not bulletproof.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thanks for your input, one question, is this a programmer's responsibility to make sure not using `p2` or is there a way to avoid this automatically? – user3727663 Jun 10 '14 at 21:21
  • @user3727663 Unfortunately, there is no easy way of avoiding this automatically in C, so making sure that access through a dangling pointer never happens remains programmer's responsibility. – Sergey Kalinichenko Jun 10 '14 at 21:43
2
  1. Yes, p2 points to same area as p1.
  2. Apparently, memory is freed, but it wasn't reused yet (though, one value was already overwritten). After freeing memory, you're not supposed to access it via another pointer.
  3. It could lead to undefined behavior. In your case, it printed corrupted array. It also could've crashed with segmentation fault (if memory page no longer belonged to your application). Behavior could change depending on OS, compiler and other stuff, so it's better to avoid such practices.
CubiX
  • 119
  • 1
  • 3
1

1) The values stored in pointers are memory addresses. Which means, two pointers with the same value points to the same address, which means the same memory region.

2) Freeing the pointer p1 only sets the value of p1 to NULL and says that the memory pointed to by p1 is free to use and it's no longer reserved. But it doesn't erase the memory. It still holds it's value. But accessing it by another pointer that still has the address is an undefined behavior as it can be reserved for another thing.

3) Yes it's normal as it's already explained in (2); the memory region is not erased or set to 0s and p2 still points to the address which means it still prints the same value

Note that if the memory region is reserved by later by malloc, printing p2 may print another value if the memory region is modified.

rullof
  • 7,124
  • 6
  • 27
  • 36