C++ 删除c+中指针数组的每个元素指向的对应元素+;

C++ 删除c+中指针数组的每个元素指向的对应元素+;,c++,algorithm,pointers,delete-operator,C++,Algorithm,Pointers,Delete Operator,假设我有一个指针数组,声明为: MyObject** myArr = new MyObject*[someSize] ; 然后,我通过 myArr[i] = myObjectInstance 现在,我想删除这个数组的每个指针指向的每个元素。那么正确的方法是什么呢? 我认为delete[]myArr不起作用。事实上,delete[]myArr是正确的,因为myArr是动态分配的对象 如果执行任何myArr[i]=myObjectInstance操作,则可能需要先取消分配一些myArr[i],其

假设我有一个指针数组,声明为:

MyObject** myArr = new MyObject*[someSize] ;
然后,我通过

myArr[i] = myObjectInstance
现在,我想删除这个数组的每个指针指向的每个元素。那么正确的方法是什么呢?
我认为
delete[]myArr
不起作用。

事实上,
delete[]myArr
是正确的,因为
myArr
是动态分配的对象

如果执行任何
myArr[i]=myObjectInstance
操作,则可能需要先取消分配一些
myArr[i]
,其中动态分配了
myObjectInstance
,例如:

myArr[i] = new MyObject;
删除myArr[i]将在以下情况下崩溃:

MyObject m;
myArr[i] = &m;
在动态分配所有位置的情况下,您可以使用
for
来释放内存:

for (int i = 0; i < someSize; ++i)
    delete myArr[i];
for(int i=0;i
事实上,
delete[]myArr
是正确的,因为
myArr
是动态分配的对象

如果执行任何
myArr[i]=myObjectInstance
操作,则可能需要先取消分配一些
myArr[i]
,其中动态分配了
myObjectInstance
,例如:

myArr[i] = new MyObject;
删除myArr[i]将在以下情况下崩溃:

MyObject m;
myArr[i] = &m;
在动态分配所有位置的情况下,您可以使用
for
来释放内存:

for (int i = 0; i < someSize; ++i)
    delete myArr[i];
for(int i=0;i
用于(int i=0;i
那就行了。无论如何,您都必须访问每个元素并单独删除它,然后使用
delete[]myArr删除数组

但动态分配阵列可能是一件麻烦的事情。为了保持如此传统,如果您能够使用它,我将推荐
std::vector
(或者任何有意义的STL容器)。您仍然需要逐个删除所有元素,但现在不必担心数组本身

如问题注释中所述,如果使用指向每个元素的智能指针,则无需手动删除任何内容。

for(int i=0;i
那就行了。无论如何,您都必须访问每个元素并单独删除它,然后使用
delete[]myArr删除数组

但动态分配阵列可能是一件麻烦的事情。为了保持如此传统,如果您能够使用它,我将推荐
std::vector
(或者任何有意义的STL容器)。您仍然需要逐个删除所有元素,但现在不必担心数组本身


如问题注释中所述,如果使用指向每个元素的智能指针,则无需手动删除任何内容。

先删除每个对象,然后删除整个数组:

for(int i = 0; i < someSize; i++)
{
    delete myArr[i];
}
delete[] myArr;
for(int i=0;i
首先删除每个对象,然后删除整个数组:

for(int i = 0; i < someSize; i++)
{
    delete myArr[i];
}
delete[] myArr;
for(int i=0;i
您可以使用标准算法
std::for\u each
和函数对象
std::default\u delete

这是一个演示程序

#include <iostream>
#include <memory>
#include <algorithm>

struct A
{
    static size_t i;
    A() { i++; }
    ~A() { std::cout << --i << ": ~A()\n"; }
};

size_t A::i = 0;

int main() 
{
    const size_t N = 10;

    A **p = new A *[N];

    for ( size_t i = 0; i < N; i++ )
    {
        p[i] = new A();
    }

    std::for_each( p, p + N, std::default_delete<A>() );

    delete []p;

    return 0;
}
如果要按与创建顺序相反的顺序删除数组元素,则可以编写

std::for_each( std::reverse_iterator<A **>( p + N ), 
               std::reverse_iterator<A **>( p ), std::default_delete<A>() );
std::for_each(std::reverse_迭代器(p+N),
std::reverse_迭代器(p),std::default_delete();

您可以使用标准算法
std::for\u each
和函数对象
std::default\u delete

这是一个演示程序

#include <iostream>
#include <memory>
#include <algorithm>

struct A
{
    static size_t i;
    A() { i++; }
    ~A() { std::cout << --i << ": ~A()\n"; }
};

size_t A::i = 0;

int main() 
{
    const size_t N = 10;

    A **p = new A *[N];

    for ( size_t i = 0; i < N; i++ )
    {
        p[i] = new A();
    }

    std::for_each( p, p + N, std::default_delete<A>() );

    delete []p;

    return 0;
}
如果要按与创建顺序相反的顺序删除数组元素,则可以编写

std::for_each( std::reverse_iterator<A **>( p + N ), 
               std::reverse_iterator<A **>( p ), std::default_delete<A>() );
std::for_each(std::reverse_迭代器(p+N),
std::reverse_迭代器(p),std::default_delete();

让我们假设所有
myObjectInstance
都是指向堆分配对象的指针(如果不是这样,请参见@JoãoPaulo的答案),并且不涉及自定义
新建
删除

for(size\u t idx=0;idx
潜在的陷阱是什么

嗯,有很多。如果只初始化了一些数组元素,该怎么办?另一个将处于不确定状态,删除它们将导致未定义的行为

另外,如果多个数组元素指向同一个对象呢?然后尝试多次删除对象。这也会导致未定义的行为

这并不意味着你不能使用这种幼稚的方法,它只是提醒你一些先决条件:

  • 确保数组的每个元素都初始化为“指向某个堆分配对象的指针”或
    nullptr
    (删除
    nullptr
    是安全的)
  • 确保不删除对象两次

  • 让我们假设所有
    myObjectInstance
    都是指向堆分配对象的指针(如果不是这样,请参阅@JoãoPaulo的答案),并且不涉及自定义
    new
    delete

    for(size\u t idx=0;idx
    潜在的陷阱是什么

    嗯,有很多。如果只初始化了一些数组元素,该怎么办?另一个将处于不确定状态,删除它们将导致未定义的行为

    另外,如果多个数组元素指向同一个对象呢?然后尝试多次删除对象。这也会导致未定义的行为

    这并不意味着你不能使用这种幼稚的方法,它只是提醒你一些先决条件:

  • 确保数组的每个元素都初始化为“指向某个堆分配对象的指针”或
    nullpt