0

假设我有一个这样的指针:

int *thingy;

在某些时候,可能会或可能不会调用此代码:

thingy=new int;

我怎么知道我是否可以这样做:

delete thingy;

我可以bool为每个指针使用 a 并将 bool 标记为true每当我使用 时new,但我有很多指针,这会变得非常笨拙。

如果我没有调用newthingy,调用delete它可能会导致崩溃,对吧?

我搜索了很多,但找不到明显适合我情况的答案。

编辑:我需要能够delete多次指向指针,而指针不一定指向任何数据。如果这是不可能的,我将不得不重新编写我的代码。

4

4 回答 4

4

始终将其初始化为 NULL

int *thingy = NULL;

接着

delete thingy;
thingy = NULL;

即使 thingy 为 NULL 也是有效的。您可以根据需要多次删除,只要thingy不会NULL delete产生不必要的副作用。

于 2013-04-17T03:12:02.097 回答
2

没有内置方法可以判断特定指针值是否可用delete。相反,您只需设计程序来做正确的事情,最好是根据您的要求仔细设计资源所有权策略,并使用 RAII 之类的方法来实施它们。

给定适当的 RAII 类型,您将不需要delete在代码周围分散 s 或其他资源管理命令。您将简单地初始化和使用适当类型的对象,并将清理工作留给对象本身。例如,如果 RAII 类型unique_ptr对应于您要使用的所有权策略,那么您可以通过以下方式管理对象:

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

无需手动清理,因为unique_ptr它会为您处理好。

另一方面,如果您尝试直接管理资源,您最终会得到大量代码,例如:

int *thingy = nullptr;

// ...

thingy = new int;

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

delete thingy;
thingy = nullptr;
于 2013-04-17T03:45:46.423 回答
0

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();
于 2013-04-17T04:37:29.993 回答
0

没有内置的 C++ 工具来识别指针是否指向堆数据并且可以安全地deleted。删除 NULL 指针是安全的,您可以将已删除数据的每个指针设置为 NULL。但这无助于区分指向堆数据的指针和指向其他数据或代码的指针。

当您的操作系统启动一个进程时,它会将代码和数据部分定位到特定的数据区域。在 Windows 中,这部分由 EXE 文件的 PE 头控制。因此,内存区域的实际地址可能会有所不同。但是您可以确定这些区域的位置:

  • 代码
  • bss
  • 数据

在获得每个区域的地址范围后,您可以区分指向堆数据的指针(适合删除的地方)和指向堆栈数据的指针。这使您可以区分delete不能删除的指针和数据。

于 2013-04-17T04:21:42.603 回答