填充指针数组,退出时删除

时间:2011-08-26 12:55:09

标签: c++ arrays pointers

在C ++中,让我们说我正在创建一个指针数组,每个元素应该指向一个数据类型MyType。我想在函数fillArPtr(MyType *arPtr[])中填充此数组。让我们说我可以使用函数createObject(int x)创建MyType对象。它的工作方式如下:

MyType *arptr[10]; // Before there was a mistake, it was written: "int *arptr[10]"
void fillArPtr(MyType *arptr[])
{
    for (int i = 0; i < 10; i++) 
    {
        MyType myObject = createObject(i);
        arptr[i] = new MyType(myobject);
    }
}

这是最好的方法吗?在这个程序中,我应该如何使用delete删除由“new”创建的对象(或者我应该使用delete?)

6 个答案:

答案 0 :(得分:1)

for (int i = 0; i < 10; i++) 
{
    delete arptr[i];
    arptr[i] = 0;
}

我建议你研究一下boost shared_ptr(也在TR1库中)

已经好多了:

 std::vector<MyType*> vec;
 for (int i=0; i<10; i++)
    vec.push_back(new MyType(createObject(i));

 // do stuff

 // cleanup:
 while (!vec.empty())
 {
     delete (vec.back());
     vec.pop_back();
 }

为明星拍摄:

 typedef boost::shared_ptr<MyType> ptr_t;
 std::vector<ptr_t> vec;
 for (int i=0; i<10; i++)
    vec.push_back(ptr_t(new MyType(createObject(i)));

答案 1 :(得分:1)

既然你问过“最好的方法是什么”,那么让我来看看这个问题并提出更多类似C ++的选择。由于您的createObject已经按值返回对象,因此以下内容应该有效:

#include <vector>

std::vector<MyType> fillArray()
{
  std::vector<MyType> res;
  for (size_t i = 0; i != 10; ++i)
    res.push_back(createObject(i));
  return res;
}

现在您根本不需要进行任何内存管理,因为分配和清理是由vector类完成的。像这样使用它:

std::vector<MyType> myArr = fillArray();
someOtherFunction(myArr[2]);   // etc.
someLegacyFunction(&myArr[4]); // suppose it's "void someLegacyFunction(MyType*)"

但是,如果您对手动内存管理和指针有真正的要求,但最好是使用示例。

答案 2 :(得分:0)

你基本上会遍历数组的每个元素并在其上调用delete,然后将元素设置为0或null。

   for (int i = 0; i < 10; i++)
   {
       delete arptr[i];
       arptr[i] = 0;
   }

另一种方法是使用std :: vector。

答案 3 :(得分:0)

如果您不必在任何地方返回数组,请使用auto_ptrs数组。只要您不制作auto_ptrs的副本,它们就不会更改所有权,并且自退出RAII以来,它们将在退出函数时释放其资源。它也已经是标准的一部分了,所以不需要使用它来提升:)它们在大多数地方都没用,但这听起来不错。

答案 4 :(得分:0)

您可以使用delete objPtr删除已分配的对象。在你的情况下,

for (int i = 0; i < 10; i++) 
{
  delete arptr[i];
  arptr[i] = 0;
}

要记住的经验法则是,如果使用new分配对象,则应delete。如果使用new[N]分配对象数组,则必须delete[]

不要将指针粘贴到原始数组中,而是查看std::arraystd::vector。如果您还使用智能指针(例如std::unique_ptr)来保存std::array内的对象,则无需担心删除它们。

typedef std::array<std::unique_ptr<MyType>, 10> MyTypeArray;
MyTypeArray arptr;

for( MyTypeArray::iterator it = arptr.begin(), int i = 0; it != arptr.end(); ++it ) {
  it->reset( new MyType( createObject(i++) ) );
}

完成使用后,您无需担心删除它们。

使用createObject(int x)的{​​{1}}函数是否可以创建对象并返回指向此的指针?在这种情况下,您还需要删除它,因为在此声明中

new

您正在制作new MyType( createObject(i++) ) 返回的对象的副本,但原件会被泄露。如果您同时更改createObject以返回createObject而不是原始指针,则可以防止泄漏。

如果std::unique_ptr<MyType>正在堆栈上创建对象并按值返回它们,则上述内容应该可以正常工作。

如果createObject没有使用createObject来创建对象,而是在堆栈上创建它们并返回指向这些对象的指针,那么你的程序将无法正常工作,因为堆栈当new退出时,对象将被销毁。

答案 5 :(得分:0)

您的方法将指针数组放在堆栈上,这很好。我想我会指出也可以存储你的指针数组on the heap。如果您希望阵列超出当前范围

,请执行此操作
MyType **arptr = new MyType[10]; 
void fillArPtr(MyType *arptr[])
{
    for (int i = 0; i < 10; i++) 
    {
        MyType myObject = createObject(i);
        arptr[i] = new MyType(myobject);
    }
}

如果这样做,请不要忘记从堆中删除数组本身

for ( int i = 0 ; i < 10 ; i++ ) {
    delete arptr[i];
}
delete [] arptr;

如果你打算使用vector,并且事先知道数组的大小,你应该预先调整数组的大小。你会得到更好的表现。

vector<MyType*> arr(10);