How to detect if a pointer was deleted and securely delete it?

50,182

Solution 1

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.

Solution 2

This is a good question, but one of the fundamental truths of working in a manually memory managed environment (like C/C++ and its cousins) is that there's no good way of looking at a pointer after the fact and asking whether it's valid-- once it's become invalid, it's gone, and looking at it is prone to blowing up. Your job is to make sure that it's never deleted or freed more than once, and never accessed after that time.

Definitely look at the smart pointers, which were invented to make programmer's lives easier in just these circumstances. (The more traditional method is to be careful, not screw it up, and then maybe assign NULL to the pointer when you know it's been deleted, as Alok says.)

Solution 3

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.

Solution 4

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

Solution 5

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.

Share:
50,182
ahmedsafan86
Author by

ahmedsafan86

Software Developer @ Authority Partners Things I Know: { C#, .net, .net core, EntityFramework, WebApi Microservices, Azure Servic Bus Microsoft_Dynamics_365 javascript, typescript, angular Unit Testing } Things I care about { TDD, Clean Architecture, Clean Code, Design Patterns }

Updated on July 09, 2022

Comments

  • ahmedsafan86
    ahmedsafan86 almost 2 years

    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 code it threw an exception that can't be handled.

    I was wondering if there is a way to check or try delete the pointer ? any reference about advanced memory operations.

    also i want to master the un-handled exceptions of pointers and the access to protected or access is violation ,... this kind of error.

    thanks for those who give some of their knowledge and their time to help other people and share their benfits


    Update

    The big advice from a lot of modern c++ developers community is - Use smart pointers or try to avoid the use of raw pointers. But for throw security and insuring free of memory (ISO_CPP_FAQ) and of course if you want to avoid the small overhead of using smart pointers[may not be noticeable always but they have overhead] you can write your custom methods that deal with raw pointers [type*] - this is not general. Prefer always smart pointers to raw pointers.

    In 'Going Native 2013' a common advice given was - Never use raw pointers.

  • James Kanze
    James Kanze about 11 years
    None of the solutions you present is really general. Smart pointers only work is special situations. Setting the pointer you delete to null doesn't help much, since it doesn't affect other pointers, and hunting down the problem after the fact is very, very difficult. The only real solution is design, up front, so that the lifetime of the (very few) dynamically allocated objects is determined.
  • Alok Save
    Alok Save about 11 years
    @JamesKanze: Its true that a well designed application will rarely face such problems and one should always design to strictly determine & limit object lifetimes. As much true that fact is the other bitter truth is that properly designed applications only exist in a ideal world, while most of us have to work with applications which already have these problems.You don't create them but inherit them.
  • 4pie0
    4pie0 about 11 years
    one could think that shared_ptr<> by default is valid also for arrays: be careful though
  • James Kanze
    James Kanze about 11 years
    Smart pointers don't necessarily help, and they can even aggravate the situation.
  • James Kanze
    James Kanze about 11 years
    This isn't unique in C++. Globally, Java doesn't give you an automatic solution either---it's garbage collection does allow you to implement one, but you still have to implement it yourself. (And of course, if you're doing anything critical in C++, you'll be using garbage collection as well, precisely so that you can reliably detect when you're accessing an already deleted object.)
  • James Kanze
    James Kanze about 11 years
    If the application isn't properly designed, it won't work, regardless of what you do after the fact.
  • ahmedsafan86
    ahmedsafan86 over 10 years
    @Saqlain: InterlockedIncrement is an atomic operation and it doesn't have a noticeable effect on the performance, if so just using the plain pointers in the low level will do it, but the problem that make you always stick with the smart pointers is the no throwing exception guarantee.