Can I create a C++ "zap" function that works on a pointer if it hasn't had memory allocated to it?
I have a zap() function written to deallocate a 1-d array as follows.
void zap(double *(&data))
{
if (data != NULL)
{
delete [] data;
data = NULL;
}
return;
}
I was under the impression that if data != NULL
would not try to deallocate memory that had never been allocated, but I think I am mistaken. I am having the following implementation problem.
void fun()
{
int condition = 0;
double *xvec;
double *yvec;
allocate_memory_using_new(yvec); //a function that allocates memory
if (condition == 1) allocate_memory_using_new(xvec);
//some code
//deallocate memory:
zap (yvec);
zap (xvec); //doesn't work
return;
}
The output is the following:
Unhandled exception at 0x6b9e57aa (msvcr100d.dll) in IRASC.exe: 0xC000000开发者_Go百科5: Access
violation reading location 0xccccccc0.
So I realize it is not a desirable thing to try to call zap when it is obvious that the pointer was never actually used. I am just wondering if there is a way to check the address of the pointer at some point in the zap() function to avoid the exception. Thanks in advance for your help and insight!
Pointers do not get magically initialized to 0, only when they are global or static. You need to do so:
double *xvec = NULL;
double *yvec = NULL;
If you do not, they contain random junk that was left on the stack where they are created. And this junk is most of the time not NULL
.
Also, you do not need to check against NULL
, as delete
is a no-op in that case:
double* xvec = NULL;
delete xvec; // perfectly valid
Further, if you're working with Visual Studio 2010, I recommend to use nullptr
instead of NULL
.
The values of xvec and yvec point to random numbers, not NULL. I think your allocate_memory function isn't working properly, as it usually would return a pointer to a block of memory, which you would assign to xvec and yvec
In C++ pointers are not initialized automagically to NULL as in other languages (think Java), so the value of xvec
(pointer) is undefined, and might or not be NULL when you test.
void fun()
{
double *xvec; // value of xvec undefined, might be 0 or not
// ...
zap (xvec); // if it is not 0, you will try to delete: Undefined Behavior
}
The simple solution is initializing the pointer in the definition double *xvec = 0;
. Also, you do not need to test for NULL (or 0
) in your zap
function, delete
will not cause undefined behavior if called on a null pointer:
template <typename T>
inline void zap( T *& p ) {
delete p;
p = 0;
}
I've concluded the the array forms of new
and delete
qualify as C++ anti-patterns -- they seem reasonable, but in reality almost any and all use of them is basically guaranteed to lead to more grief and problems than usable code.
As such, I'd say that trying to fix your zap
is a bit like finding finding a woman who's just been in a fire and gotten 3rd degree burns on at least 85% of her body, and trying to make her better by trimming the fingernail she broke while escaping from the fire.
精彩评论