0

Hello I am leaning c in school, and having a little confusion learning about dynamic memory allocation.

here, I allocated 10*4bytes of memory to a pointer 'a'. then assigned 10 values.

what I am confused on is that I do not know what free() does.

I thought it releases the allocated memory of the pointer, therefore it will also releases the values that are assigned.

But after free(), I printed out the values of a, and they are still there.

so what is exactly "releasing the memory" or de-allocateing the memory?

I guess it is nothing with the values that already assigned. Could you explain what I am confusing ?

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


int* array_of_squares(int n)

{ 
  int* ret = (int*) malloc(n * sizeof(int));
  
  if (ret == NULL)
  
    return NULL;

  for (int i = 0; i < n; i++)
  
    ret[i] = i*i;
    

  return ret;
}

int main() { 
  int size = 10;
  int* a = array_of_squares(size);
  
  if (a == NULL)
  {
    printf("malloc failed");
    return -1;
  }    

  for (int i = 0; i < size; i++)
 
    printf("a[%d] = %d\n", i, a[i] );

  printf("\n---------------------------\n");
  
  free(a);
  //after free, the memory of pointer a is released, the values are still there. what is the point of using free?

for (int i = 0; i < size; i++)
  //until i hits 10 , so 10 times for loop
    printf("a[%d] = %d\n", i, a[i] );

  return 0;
}

output is

a[0] = 0
a[1] = 1
a[2] = 4
a[3] = 9
a[4] = 16
a[5] = 25
a[6] = 36
a[7] = 49
a[8] = 64
a[9] = 81

---------------------------
a[0] = 0
a[1] = 1
a[2] = 4
a[3] = 9
a[4] = 16
a[5] = 25
a[6] = 36
a[7] = 49
a[8] = 64
a[9] = 81
  • 4
    "Releasing memory" means making it available for future allocations (or possibly, and more rarely, returning it to the operating system). It doesn't mean that the memory will be scrubbed clean, only that it will be reused for something else after further calls to `malloc()`. – user4815162342 Oct 05 '21 at 19:56
  • 7
    Calling `free` is like checking out from a hotel room. It means you give the keys back so that it can be given to someone else at some point but it does not mean the room is immediately cleaned out. If you look in the room at any point after checking out it may or may not have the same contents as when you checked out. But just as breaking back into the room after checking out is illegal, so is looking at memory you have freed - it should never be done. – kaylum Oct 05 '21 at 20:00
  • 3
    To elaborate, it is undefined behaviour to use memory after free. This means your program may sometimes misbehave due to broken assumptions in a very strange way if you do that. The problem with undefined behaviour is that your program will not misbehave predictably. An unrelated code change might trigger the strange behaviour. A new compiler version might compile it in a strange way. You never know if and when it will break. – Louis Cloete Oct 05 '21 at 20:05
  • 2
    Somewhat related C++ question (regarding local variables whose lifetime ended, instead of dynamic memory whose lifetime ended) with a very interesting analogy in the accepted answer, which also applies in this case: [Can a local variable's memory be accessed outside its scope?](https://stackoverflow.com/a/6445794/12149471) – Andreas Wenzel Oct 05 '21 at 20:15
  • 2
    an additional thought.. C is about speed. An implementation could "clear" the values after `free`, but that would take time and is ultimately useless. What would clearing the values mean anyway, setting to zeros? What if you have data where 0s are perfectly valid, such as black bitmap image data? Makes no sense to clear that to what it already is. Keep this in mind if you're ever dealing with sensitive data, like passwords or keys. They can hangout in memory even after you're done with them. – yano Oct 05 '21 at 20:17
  • @kaylum: I believe the analogy with the hotel room originated in the post that I linked to in my previous comment. – Andreas Wenzel Oct 05 '21 at 20:25
  • 1
    Hayato Koyama, "But after free(), I printed out the values of ..." --> don't do that. After `free()`, the former address is not specified to be valid - anything may happen, including reporting prior data. – chux - Reinstate Monica Oct 05 '21 at 20:46
  • Hayato Koyama, **why** are you interested in the free'd data? – chux - Reinstate Monica Oct 05 '21 at 20:48
  • @user4815162342 thank you for the comment! an additional question, the fact that the values are still there after I free them , but where are those memories after free()? if the memory that they were in is released, where do they go? they need to be in some memories right? – Hayato Koyama Oct 05 '21 at 20:49
  • @kaylum Thank you for your comment! but the fact that after free() and the values are still there, which memory are they in ? can they stay in that room until next customer comes to the memory? – Hayato Koyama Oct 05 '21 at 20:53
  • "Which memory are they in" - possibly still the same memory. But the point is you don't know and have not control over what will happen to that memory after you free it. The contents may stay the same but it may be changed. It may even be blown up - returned to the OS so it in effect doesn't exist anymore. You can certainly "try" to access the memory but the result is indeterminate - it may get the previous values, it may get different values, it may even crash the program in the case that the OS has removed that memory completely from the process address space. – kaylum Oct 05 '21 at 21:05
  • @chux-ReinstateMonica Thank you for your comment. I just want to know what de-allocating the memory or"releasing the memory " means, because that sounds to me like that the values have no longer place(memory) to be in . – Hayato Koyama Oct 05 '21 at 21:06
  • Releasing the mem from the app perspective means giving it back to the heap manager. The heap manager marks it as free and then may either leave it there in a free list to be used for later allocations or it may give it back to the OS. Leaving it in a free list means it's still there in the process address space but doesn't belong to the app code and it should never be accessed. Giving it back to the OS means that the OS removes it from the process address space which makes it virtually inaccessible. – kaylum Oct 05 '21 at 21:09
  • @HayatoKoyama "releasing the memory " tells the (operating) system that code no longer needs that memory (and code will not attempt to use it). The system is not require to zero it, make it inaccessible, keep it accessible, save it for re-use - anything. That memory is no longer the code's concern. – chux - Reinstate Monica Oct 05 '21 at 21:10
  • FWIW - this is a standard security concern. If you have heap or stack memory you use for sensitive information (passwords, keys, etc.) it's secure to "clear" that memory when you're done with it - zero it out or write garbage to it. As you've discovered the values live on in memory. This is true even after you reboot the computer. Even removing power doesn't guarantee memory will be cleared if it's only for a short time (see https://en.wikipedia.org/wiki/Cold_boot_attack). – Pat9RB Oct 06 '21 at 02:06
  • @HayatoKoyama `malloc()` is, in its essence, not as magical as you imagine. It just provides bookkeeping over pieces of a large chunk of memory (often called "arena"). From its perspective "allocating" means handing out a pointer to a piece of that arena to a new owner, and "deallocating" means making a note that a particular piece is now available to give to a new owner. Your question "where does the memory _go_?" doesn't really make sense - after `free()` the data remains right where it was, but that piece of memory will be given to a new owner after the next `malloc()`, so you can't use it. – user4815162342 Oct 07 '21 at 12:02

0 Answers0