How do I know if a pointer has been assigned data via 'new'?

丶灬走出姿态 提交于 2019-12-14 03:15:25

问题


Say I have a pointer like this:

int *thingy;

At some point, this code may or may not be called:

thingy=new int;

How do I know if I can do this:

delete thingy;

I could use a bool for every pointer and mark the bool as true whenever the I use new, but I have many pointers and that would get very unwieldy.

If I have not called new on thingy, calling delete on it would likely cause a crash, right?

I searched around quite a bit but could find no answer that clearly fit my situation.

EDIT: I need to be able to delete the pointers as many times as I like without the pointers necessarily pointing to any data. If this is impossible I'll have to re-write my code.


回答1:


Initialize it to NULL always

int *thingy = NULL;

and then

delete thingy;
thingy = NULL;

is valid even if thingy is NULL. You can do the delete as many times as you want as long as thingy is NULL delete will have no unwanted side effects.




回答2:


There's no built-in way to tell if a particular pointer value is deleteable. Instead you simply have to design the program to do the right thing, preferably by carefully designing resource ownership policies in line with your requirements and them implementing them with something like RAII.

Given appropriate RAII types you will not need to scatter deletes or other resource management commands around your code. You will simply initialize and use objects of the appropriate types, and leave clean up to the objects themselves. For example if the RAII type unique_ptr corresponds to an ownership policy you want to use then you can manage an object this way:

unique_ptr<int> thingy {new int};
// use thingy ...

There's no need to manually cleanup, because unique_ptr takes care of that for you.

On the other hand if you try to manage resources directly you end up with lots of code like:

int *thingy = nullptr;

// ...

thingy = new int;

try {
    // something that might throw
} catch(...) {
    delete thingy;
    thingy = nullptr;
    throw;
}

delete thingy;
thingy = nullptr;



回答3:


There is no builtin C++ tool to identify if a pointer points to heap data and can safely deleted. It's safe to delete a NULL pointer and you can set every pointer whose data has been deleted to NULL. But this doesn't help to differentiate between pointers to heap data and pointers to other data or to code.

When your operation system starts a process it will locate the code and data sections to specific data areas. In Windows this is partially controlled by the PE header of the EXE file. Therefore the actual address of the memory regions may vary. But you can identify where theses regions are located:

  • code
  • bss
  • data
  • stack
  • heap

After obtaining the address range for each region you can differentiate between a pointer to the heap data (where delete is appropriate) and a pointer to stack data. This allows you to differetiate between deleteable and data whose pointer you must not delete.




回答4:


Write a wrapper class that does the tracking for you, eg:

template<typename T>
class ptr_t
{
private:
    T* m_ptr;
    bool m_delete;

    ptr_t(const ptr_t&) {}
    ptr_t& operator=(const ptr_t&) { return *this; }

public:
    ptr_t()
        : m_ptr(NULL), m_delete(false)
    {
    }

    ptr_t(T *ptr, bool del)
         : m_ptr(ptr), m_delete(del)
    {
    }

    ~ptr_t()
    {
       reset();
    }

    void assign(T *ptr, bool del)
    {
        if (m_delete)
            delete m_ptr;
        m_ptr = ptr;
        m_delete = del;
    }

    void reset()
    {
        assign(NULL, false);
    }

    operator T*() { return m_ptr; }
    bool operator!() const { return (!m_ptr); }
};

typedef ptr_t<int> int_ptr;

.

int_ptr thingy;
...
thingy.assign(new int, true);
...
thingy.reset();

.

int i;
int_ptr pi;
...
pi.assign(&i, false);
...
pi.reset();


来源:https://stackoverflow.com/questions/16050793/how-do-i-know-if-a-pointer-has-been-assigned-data-via-new

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!