Should a warning or perhaps even an assertion failure be produced if delete is used to free memory obtained using malloc()?
开发者_Python百科In C++ using delete
to free memory obtained with malloc()
doesn't necessarily cause a program to blow up.
Should a warning or perhaps even an assertion failure should be produced if delete
is used to free memory obtained using malloc()
?
Why did Stroustrup not have this feature on C++?
In C++ using delete to free memory obtained with malloc() doesn't necessarily cause a program to blow up.
No, but it does necessarily result in undefined behavior, which means that anything can happen, including the program blowing up or the program continuing to run in what appears to be a correct manner.
Do you guys think a warning or perhaps even an assertion failure should be produced if delete is used to free memory obtained using malloc()??
No. This is difficult, if not impossible, to check at compile time. Runtime checks are expensive, and in C++, you don't get what you don't pay for.
It might be a useful option to turn on while debugging, but really, the correct answer is just don't mix and match them. I've not once had trouble with this.
delete
has a special property that free()
does not: it calls destructors, which in turn may call more deletes as that object may have allocated other things on the heap.
That said, new
also calls the object's constructor, while malloc()
does not. Don't mix these things unless you're absolutely sure you know what you're doing (and if you did, you wouldn't mix these things anyway).
In C++ using delete to free memory obtained with malloc() doesn't necessarily cause a program to blow up.
You should never do that. Although some compiler allocate memory for new using malloc, free() doesn't call destructors. So if you mix "new" with "free" you'll get memory leaks, and a lot of hard to deal with problems. Just forget it. It isn't worth the effort.
Do you guys think a warning or perhaps even an assertion failure should be produced if delete is used to free memory obtained using malloc()??
As far as I know, on MSVC trying to delete() memory allocated with malloc generates debug error (something like "pCrtBlock is not valid", although I don't remember exact message). That is - if project was built with debug crt libraries. Happens because debug new() allocates extra memory for every allocated block and this block doesn't exist in memory allocated with malloc.
Why do you think that Stroustrup did not had this feature on C++?
In my opinion, because a programmer should be allowed to shoot himself in the foot with rocket launcher, if he really wants to do that. delete() isn't even supposed to be compatible with malloc, so adding protection against total stupidity isn't worth the effort of making a feature.
A warning would be nice, but this probably does not happen because C++ was originally built upon C, so a runtime error could not be generated because malloc
is valid C.
Its still extremely bad practice to do this, even if your program does not crash...
Personally the undefined behaviour of mixing and matching memory allocations schemes makes it undesirable to even mix them within the same program/library.
There are some static analysis tools that can identify this kind of memory allocation / deallocation imbalance and generate warnings for you. However static analysis is never 100% accurate or fool-proof, as there will always be limitations in the tools ability to track variables and memory locations in the program.
Full disclosure: I work at Red Lizard Software writing the goanna static analysis tool for C/C++ and it is capable of detecting this kind of mismatch in some, not all instances.
I don't know why compilers don't seem to do this, it seems to be useful.
The compiler could certainly associate a bit of data with each pointer saying (allocated with new or allocated with malloc, or unknown) and when it found a free or a delete if the allocation didn't match it could issue a warning. There would be no overhead with doing this at run time. It wouldn't catch all mistakes but it would catch some so be useful.
At run time, the c++ runtime already puts in lots of extra information on some compilers to catch buffer overruns and so on in debug builds so I don't see why it couldnd't add a flag to a memory block to say how it was allocated and somehow report an error if it fails.
I suppose the real answer is that it would actually catch many bugs at all. There seems to be an awful lot of questions on here with a new one every day about mixing new and malloc, and yet in 10 years of programming I've never seen a program that does it. C programs use malloc, c++ programs use new and I've almost never seen them mixed. If you are using C++ you just use new for everything. I guess there is legacy code out there that was originally C an has been reused in c++ but I doubt there is enough of that for this to be a big issue in real life.
Has anyone ever had a problem with this in a real program anyway?
No.
When programming a compiler, warnings are the second hardest thing to develop.
Therefore, you usually have warnings against important thigns, as in "something that could really happen to a professional", not in a vast variety of a completely dumb misuse of the APIs. Besides, malloc and new allocated pointers may be impossible to distinguish at compile time.
No. A warning cannot be produced because it is not possible to determine whether a pointer was assigned a piece of memory from malloc, new or is just pointing somewhere at compile time.
An assertion is a nice feature and so would array bound checking, NULL pointer checks, etc.., but C++ is an unmanaged programming language and assumes you know what you are doing.
No. Can't be done. I can (legitimately and in compliance with spec) overload new() and delete() to use malloc and free (as I have done before), at which point, well, it's not really clear what your assertion would do to me.
精彩评论