-3

I wrote a simple C program which creates a singly linked list. It works; for instance, I pushed a few numbers to a list and the function print_list(...) prints the numbers to the console.

However, I then added a clear_list(...) function and called it before print_list(...) to see what would happen. After the call to clear_list, print_list still prints numbers as before.

How does print_list print numbers from freed memory? I use HeapAlloc for allocation of the list structure and HeapFree to deallocate.

Code below:

static BOOL push_list(DWORD a)
{
    LIST *ptr = NULL;

    ptr = (PLIST)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,     sizeof(LIST));
    if (ptr == NULL)
    {
        printf("Error push list\n");
        return FALSE;
    }

    ptr->i = a;

    ptr->next = LIST_HEAD;
    LIST_HEAD  = ptr;


    return TRUE;
}



void free_dir_list(void)
{
    PLIST pTemp = NULL;
    P_LIST PTR = LIST_HEAD;


    while (PTR != NULL)
    {
        pTemp = PTR;
        PTR = PTR->next;
        HeapFree(GetProcessHeap(), 0, pTemp);
    }
}
jwezorek
  • 8,592
  • 1
  • 29
  • 46
Anfield
  • 27
  • 4
  • why memory must be not accessible after HeapFree ? this is not VirtualFree. any way use memory after free is UB. can be any result here – RbMm Nov 04 '19 at 14:32
  • 1
    Read this: https://stackoverflow.com/a/6445794/584518. It's about local variables going out of scope but the very same reasoning can be applied to heap variables after free(). – Lundin Nov 04 '19 at 14:34
  • 1
    When you free memory, it doesn't physically disappear. And the freeing function doesn't modify the data of the memory it free's. Accessing memory you don't own (like after freeing it) leads to *undefined behavior*. – Some programmer dude Nov 04 '19 at 14:34
  • The thing about C and most computer processors is that checks on "invalid" memory access are rather coarse -- in fact you can almost say that there are no checks. If you allocate 6 bytes of memory and then try to access the 7th, that's undefined behavior -- but you can usually get away with it. If you allocate some memory, then free it, then try to access it, that's undefined behavior -- but you can often get away with it. – Steve Summit Nov 04 '19 at 14:39
  • What did you expect would happen when you tried this wrong thing? The check you might have expected the system to do, that would have caught your error and printed some error message -- that check does not exist. – Steve Summit Nov 04 '19 at 14:40
  • 2
    I said that these improper memory access were "undefined behavior", and undefined behavior in C is an interesting concept. It means that *anything* can happen. You might get an error message, you might not. It might do what you expect, it might not. It might do one thing today, and something else tomorrow. – Steve Summit Nov 04 '19 at 14:41
  • Ok I understand but how I can control my own memory? Because If I create a lor of memory like 15mb is it still accesible after free operation? – Anfield Nov 04 '19 at 15:00
  • 1
    If when you call e.g.: `char *buf = malloc(15000000);`, you do not get a `NULL` response, then yes, you can use the memory. If after you call `free(buf);` you _should not_ try to use it. (Note, the larger block of memory you attempt to allocate, the higher the chance a `NULL` response will occur.) Also, read this link on _[undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior)_. – ryyker Nov 04 '19 at 15:02
  • You ask _"how I can control my own memory?"_ Control what exactly? The question is unclear. Read carefully all comments and read carefully [this answer](https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794) – Jabberwocky Nov 04 '19 at 15:11
  • I will read thank you everyone ... – Anfield Nov 04 '19 at 15:19
  • I don't see `print_list`, `clear_list`, definition of `LIST` or a `main` demonstrating your prblems. Please read [ask] and produce a [mre] – klutt Nov 04 '19 at 15:23
  • Its part of big solution and sorry I can't paste code here. I create pseudo code and I didnt have any code problem.My question about memory – Anfield Nov 04 '19 at 15:24
  • You don't show the important parts. But I would assume that you do not set `LIST_HEAD` to `NULL` and the function to print the list doesn't know the list is empty. If the access to the free'd memory seems to work of causes segmentation fault is another story. – Gerhardh Nov 04 '19 at 15:49
  • @Anfield *If I create a lot of memory like 15mb is it still accessible after free operation?* The answers are "Maybe" and "Why do you care?" It might be accessible, or it might not be accessible. You don't know. You *can't* know. But most importantly, there is no situation where you even *need* to know. If you want to access the memory, and if you want a guarantee that you'll be able to, the answer is simple: *Don't free it*. – Steve Summit Nov 04 '19 at 16:48
  • This looks like an [XY Problem](http://xyproblem.info/) – Jabberwocky Nov 04 '19 at 17:13
  • If you like to make sure that freed memory is not accessible by your own code, drop all references to it and replace them with NULL. For example if you had allocated memory by `ANY_TYPE* p = malloc(ANY_SIZE);` then do not just call `free(p);` but also execute `p = NULL;`. – the busybee Nov 05 '19 at 11:06

1 Answers1

2

Using deallocated memory is undefined behavior in C.

It works here because nothing has altered the memory after it was deallocated. This is usually the case immediately after memory is deallocated. Functions like HeapFree(...) or just the standard C free(...) do not commonly zero out the memory; they just alter internal state managed by the runtime such that the memory is known to be free.

jwezorek
  • 8,592
  • 1
  • 29
  • 46