无法删除 std::vector 和 std::array?

8

我的C++类有一个析构函数,尝试删除std::vector和std::array实例变量。

#include <iostream>
#include <vector>
#include <array>

int main()
{
    std::array<int, 3> foo;
    std::vector< std::array<float, 4> > vertices;

    foo[0] = 1;
    foo[1] = 2;
    foo[2] = 3;
    std::cout << foo[0] << std::endl;
    delete foo;
    delete vertices;

    return 0;
}

我不确定如何正确释放内存 - 为什么我不能删除这些变量?

clang++ -std=c++11 -stdlib=libc++ -Weverything ccc.cpp 
ccc.cpp:14:2: error: cannot delete expression of type 'std::array<int, 3>'
        delete foo;
        ^      ~~~
ccc.cpp:15:2: error: cannot delete expression of type 'std::vector<std::array<float, 4>
      >'
        delete vertices;
        ^      ~~~~~~~~
ccc.cpp:18:2: warning: C++98 requires newline at end of file [-Wc++98-compat-pedantic]
}
 ^

9
你没有使用new进行内存分配,为什么还想使用delete释放内存呢?这些是自动变量 - 当它们超出其作用域时会被自动销毁。 - Igor Tandetnik
即使它们是类中的成员实例变量,也是吗? - ejang
是的,类的成员没有隐藏的 new 附加。 - chris
在您展示的代码中,它们不是类成员。无论如何,非静态类成员的生命周期与包含类实例的生命周期相匹配。 - Igor Tandetnik
@ejang:首先,坦率地说,“在一个类中”发生的事情与你无关。如果这个类被正确设计,它会自行处理所有事情。其次,在一个类中,std::array不会动态分配任何内存。std::vector会动态分配内存,但同样不需要你担心。 - AnT stands with Russia
1个回答

28

删除这些变量吗?你应该只delete那些通过new分配的变量。在这段代码中你使用new来分配了任何东西吗?没有。所以,停止尝试去delete它们。

对象foovertices是具有自动存储期的本地对象。这些对象的内存分配和释放都是自动的。你无法控制它们。 这完全超出了你的控制范围。

如果你想手动控制内存分配,你必须使用new动态创建这些对象。例如:

std::array<int, 3> *foo = new std::array<int, 3>();
...
(*foo)[0] = 1;
(*foo)[1] = 2;
(*foo)[2] = 3;
...
delete foo;

上面的代码是可行的。但在您的示例中没有真正的理由涉及动态内存。它可以使用自动对象完美地运行。只需停止尝试删除它们。

delete需要一个指针作为参数。当您通过new分配对象时,您将通过指针访问这些对象。这些指针是您稍后传递给delete以销毁此类对象的指针。在此代码中,这些都不适用。


如果std::array的内容是对象指针,例如"std::array<Object*, 10> myArray1;"。如果它是"Object *myArray2[10];",那么我可以调用"delete []myArray2;",这也会调用Object实例的析构函数。我能调用"delete []myArray1;"吗? - phoad
@phoad:我不确定我理解你的评论。如果myArray2被声明为Object *myArray2[10],那么你将不能执行delete[] myArray2 - AnT stands with Russia
我记得"delete[] arr;"会调用"arr"中每个对象的析构函数并释放它们。http://www.cplusplus.com/reference/new/operator%20delete[]/ "operator delete[]"是一个常规函数,可以像其他函数一样显式调用。但在C++中,delete[]是一个具有非常特定行为的运算符:使用delete[]运算符的表达式首先调用数组中每个元素的适当析构函数(如果这些元素是类类型),然后调用一个数组释放函数。"。应该是Object arr[] = new Object[10],而不是Object* arr[]吗? - phoad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接