Accessing freed pointers can cause data corruption if malloc() allocates memory in the same spot unless the freed pointer is set to NULL

Viewed 80

This Question statement is came in picture due to statement made by user (Georg Schölly 116K Reputation) in his Question Should one really set pointers to `NULL` after freeing them?

if this Question statement is true

Then How data will corrupt I am not getting ?

Code

#include<iostream>
int main()
{
    int count_1=1, count_2=11, i;
    
    
    int *p=(int*)malloc(4*sizeof(int));
    
    std::cout<<p<<"\n";
    
    for(i=0;i<=3;i++)
    {
        *(p+i)=count_1++;
    }
    
    for(i=0;i<=3;i++)
    {
        std::cout<<*(p+i)<<" ";
    }
    
    std::cout<<"\n";
    free(p);
    
    
    
    p=(int*)malloc(6*sizeof(int));
    
    std::cout<<p<<"\n";
    
    for(i=0;i<=5;i++)
    {
        *(p+i)=count_2++;
    }
    
    for(i=0;i<=3;i++)
    {
        std::cout<<*(p+i)<<" ";
    }
    
}

Output

0xb91a50
1 2 3 4
0xb91a50
11 12 13 14

Again it is allocating same memory location after freeing (0xb91a50), but it is working fine, isn't it ?

2 Answers

You do not reuse the old pointer in your code. After p=(int*)malloc(6*sizeof(int));, p point to a nice new allocated array and you can use it without any problem. The data corruption problem quoted by Georg would occur in code similar to that:

int *p=(int*)malloc(4*sizeof(int));
...
free(p);

// use a different pointer but will get same address because of previous free
int *pp=(int*)malloc(6*sizeof(int));

std::cout<<p<<"\n";

for(i=0;i<=5;i++)
{
    *(pp+i)=count_2++;
}

p[2] = 23;             //erroneouly using the old pointer will corrupt the new array
for(i=0;i<=3;i++)
{
    std::cout<<*(pp+i)<<" ";
}

Setting the pointer to NULL after you free a block of memory is a precaution with the following advantages:

  • it is a simple way to indicate that the block has been freed, or has not been allocated.
  • the pointer can be tested, thus preventing access attempts or erroneous calls to free the same block again. Note that free(p) with p a null pointer is OK, as well as delete p;.
  • it may help detect bugs: if the program tries to access the freed object, a crash is certain on most targets if the pointer has been set to NULL whereas if the pointer has not been cleared, modifying the freed object may succeed and result in corrupting the heap or another object that would happen to have been allocated at the same address.

Yet this is not a perfect solution:

  • the pointer may have been copied and these copies still point to the freed object.

In your example, you reuse the pointer immediately so setting it to NULL after the first call to free is not very useful. As a matter of fact, if you wrote p = NULL; the compiler would probably optimize this assignment out and not generate code for it.

Note also that using malloc() and free() in C++ code is frowned upon. You should use new and delete or vector templates.

Related