omn​​et ++:自我消息作为被处置对象

时间:2017-02-15 15:34:36

标签: omnet++

模拟运行但在控制台中我有这个说明。

  

未公开的对象:(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()。如果这   omn​​etpp :: 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'的时间。

3 个答案:

答案 0 :(得分:3)

您正在创建新的计时器(消息)但从不删除旧计时器。只是在处理消息时删除消息不起作用(因此错误消息)。

我的建议(对模拟没有特别了解):

  1. 在初始化函数中创建一次计时器消息(例如)
  2. in if (msg == gateCycleTimemsg) - &gt;检查计时器消息是否已经安排
  3. 如果已经安排了计时器消息,取消计时器并重新安排计时器但不创建新计时器
  4. 如果没有安排计时器,请安排(创建)它(显然是第一次)
  5. 代表else if (msg == IntervalTimemsg) - &gt;当计时器遇到(自我消息被传递)时调用它,因此只是重新安排计时器但不创建新消息。
  6. 您可以在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()只会删除最后一个对象

提议的解决方案:

  1. 在构造函数中添加:

    IntervalTimemsg = nullptr;
    
  2. 更改行:

    IntervalTimemsg = new cMessage("IntervalTimemsg"); 
    

    成:

    if (IntervalTimemsg != nullptr) {
       cancelAndDelete (IntervalTimemsg);
    }
    IntervalTimemsg = new cMessage("IntervalTimemsg");