In C++ How to decide or know if a pointer was deleted before??
when i tried to delete a pointer that was previously deleted in another part of the c
There can be three solutions. You might want to choose one depending on the effort/quality ratio you want to acheive:
Elegant and most correct solution:
Use smart pointers and you do not have to manually call delete
ever again. This is the best possible way to overcome this problem. It utilizes the principle of RAII which works perfectly for a language like C++ which does not have an in-built garbage collector.
Less elegant but workable solution:
Assign the pointer to NULL
after deletion. Calling delete
on a NULL
pointer is a no-op so it removes the need to have that extra NULL
check but this might hide some problems instead of making them visible.
Less elegant but more correct solution:
Hunt down all the multiple delete
problems by letting your program crash. You might as well use memory analyzer programs like valgrind and then fix your code to avoid all these problems.
The pointer won't tell you anything. Your design should: if you're using dynamic allocation, it's normally because your application requires the object to have a specific lifetime, so you know when to correctly delete the object. If the object is copyable, or has a lifetime which corresponds to scope, you don't (normally) allocate it dynamically.
There are, of course, exceptions in very low level code—if
you're implementing something like std::vector
, you will have
to use some sort of dynamic allocation, because the size isn't
known at compile time. But such allocations shouldn't escape;
it's the responsibility of the low level class to handle the
memory.
Finally, buffer overruns, accessing already deleted memory, and
the like are undefined behavior. They do not, in general,
result in an exception, and there's not a generic way of
handling them. (You can usually arrange to get a signal when
such things occur, but there are so few things you can do from a
signal handler, this doesn't really help much.) In general,
what you want is for the program to crash, since you don't know
what state it is in. In the rare cases where this is not the
case, you have to fall back on implementation defined
extensions, if they exist. If you compile with the /EHa
option with VC++, for example, what would normally be a crash
will be coverted into a C++ exception. But that's a VC++
extension, and you still don't know the overall state of the
program when this occurs. If it's because you've corrupted the
free space arena, there's probably not much you can do even if
you catch the exception (and there's a good chance you'll get
another exception from a destructor trying to free memory when
you unwind the stack).
use shared_ptr<>
and shared_array<>
, remember shared_ptr<>
can be used to manage memory allocated to an array only if appropriate Deleter is provided, otherwise use shared_array<>
to manage your arrays
A* a_tab=new A[100];
boost::shared_ptr<A> a_tab_ok(a_tab,ArrayDeleter<A>());
//only ok if
template <typename T>
class ArrayDeleter
{
public:
void operator () (T* d) const
{
delete [] d; //will delete array!
}
};
is provided
I know this thread is old. But if someone else is reading this, he should know about unique_ptr. shared_ptr has indeed an overhead. The counter is stored on the heap. Every time the counter is accessed, there is a risk of a processor cache mismatch. unique_ptr Is more limited but has no overhead in comparison to plain pointers. My suggestion is to prefer unique_ptr over shared_ptr when you do not need reference counting. Another important notice is, that unique_ptr works well with arrays. If i remember correctly this is also true for shared_ptr since C++17.
In C++ How to decide or know if a pointer was deleted before??
The language standard does not offer any legal way to determine whether an arbitrary pointer is valid or not.
There's one way, but it's highly compiler/OS-specific. You can either hook into the existing memory manager or replace it with your own and provide a dedicated function for pointer validation. It may be not very easy to do, though. And you don't really want to rely on this functionality if performance is critical.
Smart pointer are better choice to avoid such problems (but you must have complete understanding before using them also), but I would like to mention performance limitations associated with Smart pointers, reason is they usually use atomic operations for example InterlockedIncrement in Win32 API for reference counting. These functions are significantly slower than plain integer arithmetic. I am not sure such little performance penalty acceptable in your case or not.
What i usually do is (so i don't have to spend days later on to debug nasty bugs), i spend lot of time on design, and object lifetime, before moving for actual coding, as i delete memory I specifically set pointer to NULL, it is good practice as far as i think. Again perhaps the real solution is to spend more time on determining dependencies and object life time before moving on!