3

In the following code, delete[] is called once to free up the memory allocated by new. However, the array elements is still accessible after delete[] is called. I called delete[] twice to confirm that I am getting a double free or corruption error, which I am getting, which means the memory is freed. If the memory is freed, how am I able to access the array elements? Could this be a security issue which might be exploited, if I am reading something like a password into the heap?

int *foo;
foo = new int[100];

for (int i = 0; i < 100; ++i) {
    foo[i] = i+1;
}

cout << foo[90] << endl;
delete[] foo;
cout << foo[90] << endl;

gives the following output

91 91

and

int *foo;
foo = new int[100];

for (int i = 0; i < 100; ++i) {
    foo[i] = i+1;
}

cout << foo[90] << endl;
delete[] foo;
delete[] foo;
cout << foo[90] << endl;

gives

*** Error in./a.out': double free or corruption (top): 0x000000000168d010 ***`

scott
  • 1,557
  • 3
  • 15
  • 31
  • 1
    Deleting the array just tells the heap manager that that area of memory once again available for use in the future. It doesn't immediately overwrite the memory (because doing so would be inefficient). It does, however, mean that the area might get overwritten at any time (e.g. at the next memory allocation, which could be done by a different thread) so you aren't allowed to rely on its contents anymore. – Jeremy Friesner May 26 '16 at 14:51
  • 2
    It's a good practice to set the pointer to `nullptr` right after the `delete` (if there's a risk that the pointer might get dereferenced). That mitigates the risk of accidentally accessing de-allocated memory (as well as double deletes). – Sander De Dycker May 26 '16 at 14:54
  • 1
    Regarding the security question: it could be a security issue, if an attacker has access to your process's memory space -- but of course if an attacker can read your memory space then you're likely in trouble no matter what, because the attacker could always halt your process inside a debugger before you deleted the array, and read the password at that point. That said, some programs do manually zero out sensitive memory before freeing it (and take a number of other extra steps), for security reasons. – Jeremy Friesner May 26 '16 at 14:54
  • 1
    An interesting question and test, but you did not identify what you were expecting, and why you would expect that. null values? some sort of 'access denied' exception with process halt? A compiler warning that you did not clear the memory before the delete of it? – 2785528 May 26 '16 at 15:03
  • @DOUGLASO.MOEN I was expecting a null value, until Sander pointed out it is a good practice to set the pointer to nullptr after the delete. – scott May 26 '16 at 15:16
  • 1
    IMHO, most of your peers would revolt (against the use of that compiler) if the compiler generated code they considered unnecessary. – 2785528 May 26 '16 at 15:20
  • 2
    @scott note that setting the pointer to null only helps with the risk of accidental dereference if the dereference checks for null first. – eerorika May 26 '16 at 15:57

1 Answers1

5

The memory is free, which means it isn't attributed anymore, but the compiler's not going to take the extra effort to wipe it back to 0 everytime something's deleted.

It's also not going to take the effort to check that the memory is properly allocated before you access it - it'd reduce performance, and it assumes you don't do so. (Although tools like valgrind or debuggers can detect those wrong calls)

So it just changes the range of the memory as 'unassigned' internally, which means another call to new can use that same memory range. Then whatever data in that memory would be overwritten, and foo[90] won't return the same thing anymore.

coyotte508
  • 9,175
  • 6
  • 44
  • 63