0

Could somebody explain why this code results in heap corruption?

string someText = "hello hello";
char **arrayOfCharPtr = new char*[5];
arrayOfCharPtr[0] = new char[someText.length()];
strcpy(arrayOfCharPtr[0], someText.c_str());
delete[] arrayOfCharPtr[0];

Thanks a lot!

Johan
  • 863
  • 3
  • 13
  • 28
  • 1
    Your array is one character short, there's no space for the null character copied by `strcpy`. – user657267 Aug 06 '16 at 10:07
  • Ok, length() + 1. But why does this cause a memory leak? the strcpy-line itself does not cause an error; it is the delete-line that causes it. Why can't it just delete whatever is in arrayOfCharPtr[0] regardless of how long its content is? – Johan Aug 06 '16 at 10:23
  • 2
    "the strcpy-line itself does not cause an error" Welcome to undefined behaviour, where things can seem to work but then blow up in spooky ways miles away from the source. – user657267 Aug 06 '16 at 11:14

1 Answers1

3

You need to allocate one character more than the length of your string for storing the last '\0' character.

arrayOfCharPtr[0] = new char[someText.length()+1];

In your case the strcpy will write the last '\0' after the allocated bloc and it corrupts the heap.

Tools like valgrind can help to understand. valgrind produces the error message

==16970== Invalid write of size 1
==16970==    at 0x4C3106F: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16970==    by 0x400C47: main
==16970==  Address 0x5ab5cfb is 0 bytes after a block of size 11 alloc'd
==16970==    at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16970==    by 0x400C1C: main

which localizes the source of the error.

Franck
  • 1,635
  • 1
  • 8
  • 11