-1

I am new to the C language, and I am trying to allocate the memory dynamically with Malloc, then free the memory with "free".

I have tried searching on google but it does not make sense so far since I just started learning it.

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

int main (){
    printf("Enter your name:");


    //Here I allocate enough memory for the "sir" array.

    //allocate memory
    char *sir = (char*) malloc (100 * sizeof(char));

    //scan string. I am scanning a name e.g.: John Smith
    scanf("%[^\n]", sir);
    //size of sir
    int size = strlen(sir);
    printf("String size with strlen = %d\n", size);

    //printing the string
    for(int i = 0; i < size; i++){
        printf(" %d = [%c] ", i ,sir[i]);
    }
    //Printing J o h n _ S m i t h
    //Here I release the memory allocated    

    //release memory
    free(sir);

    //print the string after releasing memory
    printf("\n\n");
    for(int i = 0; i < size; i++){
        printf(" %d = [%c] ", i ,sir[i]);
    }
    //Printing _ _ _ _ _ S m i t h

    //After the above loop, I still have some input as well as some memory which I can access.

    // I do not understand why free does not release whole memory.
    return 0;
}

I am expecting that after the free(sir) line, the memory I am trying to access is null/unaccessible.

I understand this wrong?

Thank you in advance.

Adrian
  • 17
  • 3
  • 3
    When you sell your house and move out, you don't necessarily have to clean it. – Bathsheba Sep 16 '19 at 08:18
  • It does release the memory so it may (or may not) be reused at any time. It does not clear the contents, since that's overhead that C does not require. Accessing free'd memory gives behavior that is not predictable, so this happens in your case, in someone else's case with the same code it may break in entirely different ways. – Joachim Isaksson Sep 16 '19 at 08:19
  • Your understand that wrong, yes. Your expectation is not an unreasonable one, but it turns out to be too expensive for the O/S to actually make the now freed memory inaccessible, so it's just flagged as free. There may be other subtle changes to it now that you no longer own it, but by default it is not made off limits. – 500 - Internal Server Error Sep 16 '19 at 08:19
  • Constructive comment, but free does not destroy my house? – Adrian Sep 16 '19 at 08:20
  • It is the *ownership* that is `free`d, not the memory, which might or might not still be accessible. – Weather Vane Sep 16 '19 at 08:20
  • That's right, selling the house does not destroy it, and that's why you can still break into the house and access the things within. But perhaps the new owner will destroy it sometime. – Blaze Sep 16 '19 at 08:21
  • free() does not zero memory as a general rule. It simply releases it for re-used by a future call to malloc() – Mike Sep 16 '19 at 08:23
  • free() only marks the memory as no longer in use by your program. After that, any access to the memory is undefined behaviour. I.e. the system can (but does not have to) recycle the freed memory for other purposes. Because e.g. a web browser or another bigger piece of software will often call malloc(), free() or one of their equivalents many hundreds of times per second, the overhead is kept as small as possible by not actually deleting the contents. – TeaRex Sep 16 '19 at 08:26
  • Thank you guys for all the explanations. – Adrian Sep 16 '19 at 08:51

1 Answers1

0

This is expected undefined behaviour. After a call to free your pointer will still point to the same address. Another call to malloc may now use the freed memory, that would otherwise be reserved. If nothing has yet been written to this address however, it's contents will still be the same and since your pointer is still pointing to it, you can print the string. In general, free is used for memory management, not for setting memory to any value.

Never do this in actual code, use after free is a huge security risk.

edit: To clarify, you might not be able to access the memory at all, even if nothing is written to it. Again, there is no way of knowing beforehand.

3ch0
  • 173
  • 1
  • 7
  • So, in order to overwrite that memory, I should allocate another chunk of memory and overwrite it with new content. Also, free only releases the memory, not clean/delete its content, which can be accessed at any time, right? – Adrian Sep 16 '19 at 08:41
  • Using `malloc` again does not mean you will get the same chunk of memory. You could overwrite the content with something like `memset`, using the pointer you already have. Also, no, if the _ownership_ of the memory changes, you will not be able to access it anymore. As I said, the behaviour is completely undefined, there is no way of knowing what will happen. – 3ch0 Sep 16 '19 at 08:45