试图释放对象指针的向量时崩溃

Crash when trying to deallocate vector of object pointers

本文关键字:向量 崩溃 指针 释放 对象      更新时间:2023-10-16

我有一个指针向量:vector<Operators*> valid_start = {&negative, &values, &numbers, &bracket_left, &functions};当使用以下代码释放内存时,程序崩溃

void deallocate_vector(vector<Operators*> & a)
{
    for(int it = 0; it < a.size(); it++)
    {
        delete a[it];
    }
    a.clear();
}

我看过这些线程

vector::erase()在对象指针的vector上销毁对象本身吗?

清除指针向量

清理指针的STL列表/向量

释放存储在vector中的对象?

,看不出这段代码失败的原因。我也尝试过这种形式的释放,这也崩溃了:

for (std::vector<Operators*>::iterator it = a.begin(); it != a.end(); ++it)
{
     delete(*it);
} 
a.clear();

我已经有效地逐字复制了代码,但它仍然失败。为什么?

编辑:

否定的声明。其余指针都是相同类型的

struct Operators
{
    std::vector<std::string> members;
    std::vector<Operators*> precedents;
    std::vector<Operators*> followers;
}negative;
negative.members = {"-"};
negative.precedents = {&basic_operators, &values, &numbers, &comma, &bracket_left, &bracket_right, &factorial};
negative.followers = {&bracket_left, &numbers, &values, &functions};

这就是为什么你应该厌倦使用&在非常受控制的情况下。

我不确定Operator是什么,大概是一些类,所以我将给出一个普遍理解的类型的类似示例并解释它。考虑:

{ // Some sort of local scope
    int x = 10;
    int* xp = &x;
}

x的生命周期由编译器控制。它存在于"堆栈上",当它进入局部作用域时,在程序的执行框架内。它在作用域打开/声明时创建,并在作用域退出时删除。请注意,编译器实现细节可能意味着它实际上是在不同的时间创建/删除的(或者甚至从来没有,如果它从未被使用过),但是您可以假设在大多数情况下是这种行为。

现在,xp是指向x的指针。如果我删除xp,然后编译器删除x后面的内存,你认为会发生什么?相同的内存被删除两次——这是一种未定义的行为,往往会导致崩溃或更糟。

为了理解这个问题,你可以把看作是:

{
    int* __x = new int;
    int& x = (*__x);
    /////////////////
    x = 10;
    int* xp = &x;
    // now xp == __x
    /////////////////
    delete __x;
}

注意,这实际上不是编译器要做的;然而,这在某种程度上说明了它实际所做的外部行为。