C++ 删除指向结构的指针数组
我有以下结构:C++ 删除指向结构的指针数组,c++,C++,我有以下结构: struct Message { Agent *_agent; double _val; }; 以及以下Ptrs阵列: typedef Message* MessageP; MessageP *_msgArr; _msgArr = new MessageP[MAX_MESSAGES]; 这是将消息插入阵列的方法: void Timing::AddMessage(Agent * const agentPtr, double val) { Message
struct Message {
Agent *_agent;
double _val;
};
以及以下Ptrs阵列:
typedef Message* MessageP;
MessageP *_msgArr;
_msgArr = new MessageP[MAX_MESSAGES];
这是将消息插入阵列的方法:
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++;
}
这会同时删除每个已分配的结构还是仅释放阵列的已分配内存
正确的方法是使用for循环和write遍历整个数组
delete _msgArr[i]
最后使用delete[]\u msgArr删除分配的数组
?
谢谢 是,在对数组调用
delete[]
之前,需要循环所有元素并手动删除它们。是。但是如果你打算经常这样做的话,你可以用几行来简化这件事
#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;
#包括
//可能已经存在于boost标头中(我不记得了)
模板
无效删除函数(T*e){
删除e;
}
//然后,要删除阵列,请执行以下操作:
std::对于每个消息(\u msgArr,\u msgArr+MAX\u消息,删除\u func);
删除[]\u msgArr;
但我建议不要这样做。您可以将std::vector与auto_ptr或shared_ptr一起使用(取决于您的用例)。因此,您不必自己删除每个元素,因为auto_ptr会这样做。您只需删除std::vector,除了它位于类成员函数中,并使用
new
和delete
,这是C代码。您不需要检查new
的结果(分配错误将抛出),您不应该执行自己的动态数组(这就是std::vector
的目的),也不应该使用哑指针管理动态分配
您需要的是
std::vector
或boost的指针容器之一 delete[]将调用结构指针上的析构函数,它不会处理结构或本身指向内存的\u代理
成员。您可以在循环中调用delete\u msgar[i]。\u agent
,然后调用delete\u msgar[i]
,这将处理agent
,然后处理消息
不过,首先,您需要知道谁应该在何时摆脱代理。如果这些数据属于另一个数据结构,则在清除\u msgar
并循环执行\u delete\u msgar[i]
和delete[]时,不应清除它们代码>是您所需要的全部
如果您确实需要同时删除代理
s,您有三个合理的选择
首先,您可以给消息
一个析构函数,它将删除它的\u代理
。它还应该定义一个复制构造函数和赋值运算符,用于传递所有权或复制,或者将它们定义为private
,因此任何使用它们的尝试都将是编译时错误
其次,您可以将代理*
更改为智能指针,以便在消息
消失时删除额外的内存
第三,在去掉数组时,可以执行我上面建议的循环
除非您有充分的理由保持代码C兼容,否则我建议您使用std::vector
,并让Message
包含boost::shared\u ptr
而不是代理*
(如果您不必处理代理
,那么代理*
就可以了)。在这一点上,您不必担心:当\u msgArr
超出范围时,所有内存都会被正确清理。您是否考虑过使用标准库容器,如std::vector
或std::deque
?James有一点-标准数组非常有用(如果有时稍微慢一点,通常资源效率更高)-但是根据下面的答案,你仍然需要删除std容器中指向的对象。那么这门课程就错了。它应该涵盖STL,而不是指针或C数组。@rob:所以这门课程是反向教授的。它应该先教授简单的高级内容,然后再教授如何在引擎盖下工作。你被教授的方式现在,你先学会手动操作,然后再学会不手动操作,而是使用图书馆设施。@sbi:我从未听说过CS课程以任何其他方式教授,这一直是我深切关注的问题。人们应该知道事情是如何运作的,是的,但他们应该知道还有其他解决方案。我有enc许多长期以来的“C++程序员”很少有STL知识。更不用说很多C++教师是很瘦的C教师,我认为这是一个严重的问题。因此,从我理解的,删除[]] MSGARR不调用每个单元的删除。?我的意思是,它是否也会删除分配的数组?@rob:If\u msgArr
指向由new T[N]
创建的数组(数组形式为new
),然后delete\u msgArr
产生未定义的行为。必须使用delete
的数组形式删除它。它在每个单元格上调用析构函数,但由于单元格是指针而不是对象,因此没有析构函数操作。如果要自动删除分配的结构,请考虑对数组元素使用智能指针类型ts.你能解释一下你的第二个选择吗?当消息被删除时,使用智能指针将删除所有内存?
#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;