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 ***`

7
  • 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. Commented May 26, 2016 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). Commented May 26, 2016 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. Commented May 26, 2016 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? Commented May 26, 2016 at 15:03
  • 2
    @scott note that setting the pointer to null only helps with the risk of accidental dereference if the dereference checks for null first. Commented May 26, 2016 at 15:57

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.