删除指向struct的指针数组

时间:2010-09-09 15:51:05

标签: c++

我有以下结构:

struct Message {
    Agent *_agent;
    double _val;
};

以及以下的Ptrs数组:

typedef Message* MessageP;
MessageP *_msgArr;
_msgArr = new MessageP[MAX_MESSAGES];

这是将Message插入数组的方法:

void Timing::AddMessage(Agent * const agentPtr, double val) {

    MessageP msgPtr = new Message;
    assert(msgPtr != 0);

    //assign values:
    (*msgPtr)._agent = agentPtr;
    (*msgPtr)._val = val;

    //add to messages array:
    assert(_msgArr != 0 && _waitingMsgs<MAX_MESSAGES);
    _msgArr[_waitingMsgs] = msgPtr;
    _waitingMsgs++;

}

我的问题是删除这个数组。我想删除数组和所有已分配的结构。 如果我写:

delete [] _msgArr  

这会删除每个已分配的结构还是只释放数组的已分配内存?

正确的方法是使用for循环遍历整个数组并写入

delete _msgArr[i]

并最后删除[] _msgArr删除已分配的数组 ?

谢谢!

4 个答案:

答案 0 :(得分:4)

是的,您需要在调用阵列上的delete之前手动遍历所有元素并delete[]

答案 1 :(得分:2)

delete []将调用struct指针上的析构函数,它不会处理结构或_agent成员,它们本身指向内存。您可以在循环中调用delete _msgArr[i]._agent然后调用delete _msgArr[i],这将处理Agent,然后处理Message

首先,你需要知道谁应该摆脱Agent,以及何时。如果它们归其他数据结构所有,那么在摆脱_msgArr时就不应该删除它们,并且只需_delete _msgArr[i]循环delete [] _msgarr;就可以了。

如果您确实还需要删除Agent,则有三个合理的选择。

首先,您可以为Message提供一个将删除其_agent的析构函数。它还应该有一个复制构造函数和赋值运算符,既可以传递所有权也可以复制,或者将它们定义为private,因此任何使用它们的尝试都将是编译时错误。

其次,您可以将Agent *更改为智能指针,以便在Message消失时删除额外的内存。

第三,你可以在摆脱数组时完成上面建议的循环。

除非您有充分的理由保持代码C兼容,否则我建议您使用std::vector<boost::shared_ptr<Message> >Message包含boost::shared_ptr<Agent>而不是{{1} (如果您不必处置Agent * s,Agent就可以了)。此时,您不必担心:当Agent *超出范围时,所有内存都会被正确清理。

答案 2 :(得分:0)

不幸的是,是的。但是如果你要做很多事情,你可以用几行来简化这个事情。

#include <algorithm>
// might already exists in a boost header (i don't remember)
template <T>
void delete_func(T* e) {
    delete e;
}

// then, to delete your array :
std::for_each(_msgArr,_msgArr+MAX_MESSAGES, delete_func);
delete[] _msgArr;

但我建议不要这样做。你可以使用带有auto_ptr或shared_ptr的std :: vector(取决于你的用例)。所以你不必自己删除每个元素,因为auto_ptr会这样做。你只需要删除std :: vector

答案 3 :(得分:0)

除了它在类成员函数中并使用newdelete之外,这是C代码。你不需要检查new的结果(抛出分配错误),你不应该做你自己的动态数组(这是std::vector的用途),你不应该动态管理使用哑指针分配。

你想要的是std::vector< std::shared_ptr<Message> >或者一个boost的指针容器。