模拟运行但在控制台中我有这个说明。
未公开的对象:(omnetpp :: cMessage) Mysimulation.Switch4.eth [2] .queue.scheduler.IntervalTimemsg - 检查 模块析构函数undisposed对象:(omnetpp :: cMessage) Mysimulation.Switch5.eth [1] .queue.scheduler.IntervalTimemsg - 检查 模块析构函数
实际上这是我通过模拟反复使用两个定时消息创建的模块。我在线阅读并发现此错误与创建应删除时未删除的对象有关。
void PriorityScheduler::initialize() {
gateCycleTimemsg = new cMessage("gateCycleTimemsg");
scheduleAt(baseTime , gateCycleTimemsg);
// baseTime = 2s
}
void PriorityScheduler::handleMessage(cMessage *msg) {
if (msg == gateCycleTimemsg) {
if (currentList == (lastIntervalTime)) {
delete msg;
gateCycleTimemsg = new cMessage("gateCycleTimemsg");
scheduleAt( simTime() + gateCycleTime , gateCycleTimemsg);
...
IntervalTimemsg = new cMessage("IntervalTimemsg");
scheduleAt( simTime() + Interval , IntervalTimemsg);
}
else if (currentList == (firstIntervalTime)) {
gateCycleTimemsg = msg; // same message reused
scheduleAt(simTime() + gateCycleTime , gateCycleTimemsg);
//gateCycleTime = 10 seconds
...
IntervalTimemsg = new cMessage("IntervalTimemsg");
scheduleAt( simTime() + Interval , IntervalTimemsg);
// Interval = 1s
}
}
else if (msg == IntervalTimemsg) {
if (currentList == (lastIntervalTime));
else{
IntervalTimemsg = msg;
scheduleAt( simTime() + Interval , IntervalTimemsg);
}
}
插件路径:/home/amr/omnetpp-5.0/samples/etc/plugins;./plugins 抛出一个实例后终止调用 'omnetpp :: cRuntimeError'what():对象pk-56-145当前 (omnetpp :: cEventHeap)simulation.scheduled-events,它不可能 删除。如果在omnetpp :: cEventHeap中发生此错误,则需要 更改为在删除该对象之前调用drop()。如果这 omnetpp :: cEventHeap的析构函数和pk-56-145中发生错误 一个类成员,omnetpp :: cEventHeap需要调用drop() 析
我创建了一个构造函数和析构函数。在线阅读解决方案之后,我还创建了函数finish()。这仍然没有解决它。
我还删除了收到的每封邮件,并在发送时创建了一条新邮件,但它没有改变任何内容。
编辑我用delete msg编辑了编码;我添加了一个时间示例,并添加了以下部分,
BaseTime'BT',gateCycleTime'CT',Interval'IT'
----> BT
<---- IT1 ----> <----- IT2 ----> .........<-------- ITx -------->
<------------------------------ CT ----------------------------->
我使用相同的消息进行BT和CT,而另一条消息则是IT,因为我不知道最后一次IT'ITx'的时间。
答案 0 :(得分:3)
您正在创建新的计时器(消息)但从不删除旧计时器。只是在处理消息时删除消息不起作用(因此错误消息)。
我的建议(对模拟没有特别了解):
if (msg == gateCycleTimemsg)
- &gt;检查计时器消息是否已经安排else if (msg == IntervalTimemsg)
- &gt;当计时器遇到(自我消息被传递)时调用它,因此只是重新安排计时器但不创建新消息。您可以在OMNeT ++手册中阅读有关自我消息(通常用于计时器)的更多信息:https://omnetpp.org/doc/omnetpp/manual/#sec:simple-modules:self-messages
答案 1 :(得分:1)
通常,不应在handleMessage()函数中创建计时器,以避免在每次调用中创建和销毁对象。因此,initialize函数应该创建消息
void PriorityScheduler::initialize() {
gateCycleTimemsg = new cMessage("gateCycleTimemsg");
IntervalTimemsg = new cMessage("IntervalTimemsg");
scheduleAt(baseTime , gateCycleTimemsg);
}
并且finish函数或析构函数应该清理它们。
void PriorityScheduler::finish() {
cancelAndDelete(gateCycleTimemsg);
cancelAndDelete(IntervalTimemsg);
}
答案 2 :(得分:1)
在第
行IntervalTimemsg = new cMessage("IntervalTimemsg");
每次创建{strong> cMessage
对象的新实例,并将指向它的指针写入IntervalTimemsg
。但是,您永远不会删除IntervalTimemsg
指示的对象。因此,当第二次(和另一次)执行此行时:
因此cancelAndDelete(IntervalTimemsg)
中的finish()
只会删除最后一个对象。
提议的解决方案:
在构造函数中添加:
IntervalTimemsg = nullptr;
更改行:
IntervalTimemsg = new cMessage("IntervalTimemsg");
成:
if (IntervalTimemsg != nullptr) {
cancelAndDelete (IntervalTimemsg);
}
IntervalTimemsg = new cMessage("IntervalTimemsg");