2

I have a pointer to int, and after I call free, I see that only the first two elements get freed, the rest remain the same. Can anybody explain?

int main() {
        int* a = (int*)malloc(10*sizeof(int));

        a[0] = 12;
        a[1] = 15;
        a[2] = 100;
        a[3] = 101;
        a[4] = 102;
        a[5] = 103;
        a[6] = 109;
        a[7] = 999;

        printf("%d %d %d %d %d %d %d %d\n", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);

        free(a);
        printf("Done freeing.\n");
        printf("%d %d %d %d %d %d %d %d\n", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);

        return 0;
}

Output: (sorry for putting all the output in one line)

12 15 100 101 102 103 109 999 Done freeing. 0 0 100 101 102 103 109 999

  • 11
    Accessing memory you don't own, like memory you have passed to `free`, leads to *undefined behavior*. Which makes your program *ill-formed* and invalid. – Some programmer dude Jun 30 '17 at 15:43
  • But if I malloc'd 10*sizeof(int), shouldn't I own it? –  Jun 30 '17 at 15:45
  • 6
    free doesnt (necessarily) change the memory contents, its just that you dont own it anymore and should not be reading or writing it. It can contain anything (including your phone number) – pm100 Jun 30 '17 at 15:45
  • 1
    Yes, @bogdan, the program owns the memory it has successfully allocated, *until it frees it*. That's `free()`'s purpose. After freeing that memory, it is no longer permitted to access it, read or write. C makes no guarantee about what happens if the program attempts to do so anyway. It certainly does not promise that the memory will appear to have been set to zero. – John Bollinger Jun 30 '17 at 15:46
  • depend on implementation. – mattn Jun 30 '17 at 15:47
  • now an interesting excercize for you would be to investigate what your free implementation actually does. Why did it change some of your memory and not others, what do the values it changed it to mean. – pm100 Jun 30 '17 at 15:49
  • @pm100 Most likely, the free function did not change anything. It was something else, and this "something" can be just about anything. – klutt Jun 30 '17 at 16:17
  • The entire array is `free`d, but the act of `free`ing that memory does not cause it to be overwritten (at least, there's no requirement that it be overwritten). Obviously that memory is still there, you just don't control it anymore, and you're not supposed to try to use it. – John Bode Jun 30 '17 at 16:18

1 Answers1

5

When you invoke free, you're just telling the OS that you're done with that memory chunk. You promise not to use it again. If you break that promise, that's your problem.

Important sidenote:

Invoking if(ptr) or if(NULL != ptr) does NOT test if ptr points at an allocated memory chunk. It only tests whether it points at anything at all. Invoking free does NOT assign null to any pointers. You have to take care of that manually. I learned this lesson the hard way...

Important sidenote 2:

There's no general way to find out whether the memory ptr points at is allocated or not. Some platforms offer this feature, but not all.

Now, maybe you wonder, wouldn't it be better if free(ptr) assigned NULL to ptr? Maybe, maybe not. The downside would be that it's false safety. Consider this code:

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

What value do you expect p2 to have? It's better to learn what it actually means that a pointer is/isn't NULL.

klutt
  • 30,332
  • 17
  • 55
  • 95