使用Omnet ++创建一些开关模拟, 我正在使用cPacket封装&解封方法。
我的问题是,在这种情况下,应该在哪个模块或哪个部分销毁动态分配的内存。
例如,假设我有以下模块,它创建一个封装在另一个cPacket中的数据包,并将其发送到其他模块:
void X::initialize()
{
cPacket* packet = new cPacket("packet");
cPacket* encapsulated = new cPacket("encapsulated");
packet->encapsulate(encapsulated);
send(packet, "XtoYout")
}
逻辑思考,我认为解封装模块负责删除封装的数据包:
void Y::handleMessage(cPacket* msg)
{
cPacket* overlay_packet = msg->decapsulate();
/* DO SOMETHING */
delete msg;
delete overlay_packet;
}
但根据Omnet ++文档,decapsulate()
为我们提供了内存重复,因此最初为encapsulated
分配的内存并未真正被破坏:
摘自omnet模拟手册 - Reference Counting
5.4.5参考计数
自3.2发布以来,OMNeT ++实现了引用计数 封装的数据包,这意味着如果你dup()包含的数据包 一个封装的数据包,然后封装的数据包将不会 重复,只增加引用计数。 重复 封装的数据包延迟,直到decapsulate()实际获得 的称为即可。如果删除外部数据包而没有其decapsulate() 方法被调用,然后是封装的引用计数 数据包只是递减。封装后的数据包将被删除 它的引用计数达到零。
此外,目前尚不清楚首次封装时是否克隆了封装的数据包(因此我们可以在使用X::initialize()
之后删除packet->encapsulated(...)
已分配的内存。
文档有点模糊,但我认为这意味着在封装时cPacket中指向了encapsulated
的原始地址,因此我无法在X::initialize()
中删除:
取自Omnet ++ cPacket类引用 - cPacket encapsulate(..)
virtual void cPacket :: encapsulate(cPacket * packet)[虚] 封装数据包中的数据包。
数据包长度增加了封装的长度 分组。
重要说明:禁止在指示之后保留指示信息 它被封装了。出于性能原因,封装的数据包是 引用计数,意味着封装的数据包不是 复制数据包时重复,而是两个(所有)副本 共享相同的数据包实例。对封装进行的任何更改 数据包也会影响其他数据包。解封(甚至是 调用getEncapsulatedPacket())将创建一个自己的(非共享)副本 包裹。
所以,总结一下:
销毁cPacket* encapsulated
的已分配内存的正确位置\流量是什么?