C++ 删除运算符和数组?

C++ 删除运算符和数组?,c++,arrays,memory-management,C++,Arrays,Memory Management,我有一个abstractBase类和派生类 int main () { Base *arrayPtr[3]; for (int i = 0; i < 3; i++) { arrayPtr[i] = new Derived(); } //some functions here delete[] arrayPtr; return 0; } int main() { Base*arrayPtr[3]; 对于(int i=0;i不,您不能这样做。正如其

我有一个
abstract
Base
类和
派生类

int main ()
{
  Base *arrayPtr[3];

  for (int i = 0; i < 3; i++)
  {
    arrayPtr[i] = new Derived();
  }

  //some functions here

  delete[] arrayPtr;

  return 0;
}
int main()
{
Base*arrayPtr[3];
对于(int i=0;i<3;i++)
{
arrayPtr[i]=新派生的();
}
//这里有一些函数
删除[]arrayPtr;
返回0;
}

我不知道如何使用删除运算符。如果如上所示删除基类指针数组,这会调用派生类对象析构函数并清理内存吗?

否,必须显式删除数组中的每个项:

for (int i = 0; i < 3; ++i)
{
    delete arrayPtr[i];
}
for ( int = i; i < 3; i++ )
     delete arrayPtr[i];
for(int i=0;i<3;++i)
{
删除arrayPtr[i];
}

您必须迭代数组中的元素,
删除每个元素然后调用数组上的
delete[]
,如果已使用
new[]
动态分配该数组

在示例代码中,数组是在堆栈上分配的,因此不能对其调用
delete[]

还要确保你的
Base
类有一个
virtual
析构函数

参考资料:。

您应该改为:

 for ( int = i; i < 3; i++ )
 {
    delete arrayPtr[i];
 }

确保
Base
具有虚拟析构函数。然后,删除数组中的每个元素,然后删除数组


您应该对数组使用
std::vector
。也就是说,你真的应该使用一个为这类东西制作的容器。(这样您就不会意外地无法删除所有元素,如果抛出异常,情况肯定会如此!)Boost做到了。

您必须单独删除数组的成员。还必须确保基类具有虚拟析构函数。您可能还想考虑使它成为一个数组(或者更好地是STD::vector)的智能指针,比如BooS::SyrdypTr.< /P> < P>不,您不能这样做。正如其他人建议的那样,你必须检查每个项目并将其删除。这是一条非常简单的规则。如果使用
new
进行分配,则使用
delete
,如果使用
new[]
进行分配,则使用
delete[]
不,这并不能完全满足您的需要

这里有两点需要注意:

  • 如果动态分配数组,则使用语法
    delete[]arrayPtr
    ,如下所示:

    arrayPtr = new (Base *)[mylength];
    
    Base *array;
    array = new Base[3];
    /* do stuff */
    delete[] array;
    
    但是,在您的例子中,您有一个静态分配的数组,因此不需要删除它。但是,您确实需要删除数组中的单个元素:

    for (int i = 0; i < 3; ++i)
    {
        delete arrayPtr[i];
    }
    
    for ( int = i; i < 3; i++ )
         delete arrayPtr[i];
    
    这确保了当您在实际指向
    派生的
    基*
    上调用delete时,会调用
    派生的
    的析构函数,而不仅仅是
    的析构函数

  • 注意缺少的内容:

    int main() {
      boost::ptr_vector<Base> v;
      for (int i = 0; i < 3; i++) v.push_back(new Derived());
      // some functions here, using v[0] through v[2]
    }
    
    intmain(){
    boost::ptr_向量v;
    对于(inti=0;i<3;i++)v.push_back(新派生的());
    //这里的一些函数使用v[0]到v[2]
    }
    

    签出。

    运算符delete必须与该指针上的运算符new匹配,如果它被分配了
    new[]
    ,则必须调用
    delete[]
    ,反之亦然

    int* pInt = new int;
    delete pInt; OK
    delete [] pInt; WRONG
    
    int[] pIntArr = new int[3];
    delete [] pIntArr; OK
    delete pIntArr; WRONG
    
    在您的情况下,还有其他问题-您正在尝试删除堆栈上分配的
    文件。那不行


    在这种情况下,您必须单独删除每个指针。

    您所拥有的是未定义的行为——一个bug。每次调用
    new
    都需要匹配
    delete
    ;每次调用
    new[]
    都需要与
    delete[]
    匹配。这两者是分开的,不能混为一谈

    在您发布的代码中,在堆栈上分配了一个指向Base的指针数组。然后在堆栈上分配的数组上调用
    delete[]
    ,但不能这样做。您只能使用
    new[]
    删除堆上分配的数组

    对于分配给
    new
    的每个元素,您需要调用
    delete
    ——或者最好使用容器类,例如
    std::vector
    ,而不是使用数组

    您正在混合各种范式——数组删除运算符旨在释放由数组新运算符分配的内存,但您正在堆栈上将数组作为指针数组进行分配,然后为每个数组成员分配一个对象。在代码中,需要遍历数组

    要使用array new运算符,您需要如下声明:

    arrayPtr = new (Base *)[mylength];
    
    Base *array;
    array = new Base[3];
    /* do stuff */
    delete[] array;
    

    这为三个对象分配了一个连续的内存区域——请注意,您得到的是一个基本对象数组,而不是一个指向基本对象的指针数组。

    无需对数组调用delete[],因为它没有“newed”。我考虑过在数组上迭代,但我不知道虚拟析构函数。谢谢。Base*arrayPtr[3];不是新的,使用delete[]删除它不会做正确的事情@罗杰:意识到在我第一次发帖之后。。。已被编辑掉,但还是要感谢;)虽然“您应该使用容器”绝对是一个最好的建议,但无论如何,它不应该被太快地抛出。我的意思是1)通过手工操作了解发生了什么,然后2)在生产代码中利用像STL和Boost这样坚如磐石的库。否则,难道没有一种倾向认为图书馆所提供的容器和其他工具仅仅是黑箱吗?你觉得怎么样?格雷戈里:不同意。在某种程度上,你应该理解引擎盖下发生了什么(也许),但我不再清楚应该是什么顺序(我过去同意你)。在调用new之前,您是否应该了解malloc的工作原理?在使用dynamic_cast之前,您是否应该了解vtables是如何工作的(然后发现这不是实现的保证部分)?都不是。也就是说,你应该知道去哪里查找你需要的信息,或者和谁交谈,等等。罗杰,我明白你的意思。举个例子,您不需要知道堆内存分配的实现细节,但最好知道堆和堆栈之间的区别。您不需要知道vtable是如何实现的等等