我有以下结构:
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删除已分配的数组 ?
谢谢!
答案 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)
除了它在类成员函数中并使用new
和delete
之外,这是C代码。你不需要检查new
的结果(抛出分配错误),你不应该做你自己的动态数组(这是std::vector
的用途),你不应该动态管理使用哑指针分配。
你想要的是std::vector< std::shared_ptr<Message> >
或者一个boost的指针容器。