0

so I execute this code

#include <cstdlib>
#include <iostream>
int main()
{
    char *test = new char[10];
    strcpy(test, "Hello Ther");;
    std::cout << test << std::endl;
    delete[] test;
    std::cout << test << std::endl;
    return 0;
}

and the output is

Hello Ther

Hello Ther

It seems as though the delete[] test statement isn't doing a thing... No runtime or compile time errors at all

completely stumped me

Community
  • 1
  • 1

3 Answers3

8

After you delete[] the array, there is no more array. Any access through that pointer after that has undefined behaviour.

delete[] is supposed to call the destructors on the array elements and release the storage used by it. Since char has no destructor it simply releases the storage. Releasing the storage only means that it is no longer in use.

FWIW, there's one more instance of undefined behaviour in your code. "Hello Ther" has 11 elements: there's a null ('\0') terminator at the end. strcpying that into a buffer only 10 elements big is undefined behaviour. You need a buffer with space for 11 elements: the 10 characters of "Hello Ther" plus the null terminator.

This kind of error, a buffer overflow, is a common source of security vulnerabilities. There were famous exploits of this kind of error since at least the 1980s. It would be wise to avoid such unsafe primitives and to prefer safe modern ones (and by "modern" I mean "from the 1990s"), like std::string. Because, you know, this is the 21st century.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
3

What did you expect to happen?

When you delete a pointer all that happens is the memory that was given to you when you called new was given back to the system. If you don't allocate or touch memory in anyway after you call delete(as in your example) the old contents of memory are still likely laying around. It would be a performance hit for delete to go zero out all that memory after all(some compiler's debug builds write special values on delete to make invalid memory access easier to find). If you did go and touch memory by allocating more memory or calling a function then the value might get destroyed. Though it might not, this is why accessing a pointer after a delete is called undefined behavior.

stonemetal
  • 6,111
  • 23
  • 25
2

In C++ it is possible to access memory whether it is allocated or not. This triggers undefined behaviour but there's no check whatsoever that says whether the given memory is "accessible". This is your problem. This contrasts with VM-based languages where memory accesses are checked for you.

A common idiom to avoid this kind of mistake is to do this:

delete[] myArray;
myArray = NULL; // preferably "nullptr" in C++11

Any access to the NULL address is refused by the CPU. It will alert the OS of the error (which will likely end your program in a segfault or equivalent error).

As mentionned by stonemetal, some compilers / OSes / allocaters will check memory accesses in debug builds, but won't do it in release mode for the speed gain.

Note: If you do try to access unallocated memory randomly you will run into page errors, but that's a bit out of topic.

J.N.
  • 8,203
  • 3
  • 29
  • 39