In writing a response, I wrote some code that challenged my assumptions on how const pointers work. I had assumed const pointers could not be deleted by the delete function, but as you’ll see from the code below, that isn’t the case:
#include <new>
#include <string.h>
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const GetArray(){ return Array; }
};
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' '; //You can still modify the chars in the array, user has access
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
//Temp.GetArray() = NULL //This doesn't work
delete [] Temp.GetArray(); //This works?! How do I prevent this?
}
My question is, how do I pass the user access to a pointer (so they can use it like a char array), whilst making it so that the delete function cannot delete it, by preferably throwing some sort of complaint or exception?
If your users are using
delete[]on pointers they didn’t get fromnew[], hit them upside the head with a clue bat.There are so many reasons a pointer can be dereferenced but mustn’t be passed to delete:
mallocor some other non-newallocator.Some of these will manifest in exceptions at runtime. Others will cause crashes at some later time. All are “undefined behavior” according to the standard.
The assumption should be that a pointer cannot be used as the argument to
delete, unless explicitly stated otherwise.If entry-level programmers are making this mistake, educate them. If “experienced” developers are doing it, fire them for lying on their resume.
If you just want it to hurt when they do that, allocate the array one larger than necessary, and
return Array + 1;. Now everything will blow up if they try to usedelete[].The practical use is that it’s (more) likely to make the program crash inside the bogus call to delete, with the offending function still on the call stack. Where the original will probably continue running for a while, and finally crash in innocent code. So this helps you catch stupid users.