OMNeT++使用动态数组消息触发运行时错误求助
Hey there! Let's work through this runtime error you're hitting when using dynamic arrays in your OMNeT++ messages. I've seen this exact issue before, so let's break down what's going wrong and how to fix it.
What's Causing the Error?
The error message you're seeing:
A runtime error occured: Object is currently in (omnetpp::cEventHeap)simulation.scheduled-events, it cannot be deleted. If this error occurs inside omnetpp::cEventHeap, it needs to be changed to call drop() before it can delete that object. If this error occurs inside omnetpp::cEventHeap's destructor and is a class member, omnetpp::cEventHeap needs to call drop() in the destructor -- in module ...
Happens because you're manually interfering with OMNeT++'s built-in memory management for messages. Here's the breakdown:
- When you send a message with
send(), OMNeT++ adds it to thecEventHeap(the simulation's scheduled event queue) to deliver it later. The kernel takes ownership of the message at this point. - The auto-generated destructor for your
Msg_event_dataalready handles dynamic array cleanup, but you've modified it with explicitdelete[]calls. This conflicts with OMNeT++'s reference-counting system for messages: when the kernel still has the message in the event heap, your manualdelete[]tries to destroy an object that's still being managed by the simulation.
Step-by-Step Fix
1. Restore the Auto-Generated Destructor
First, revert your Msg_event_data::~Msg_event_data() to the version automatically created by the OMNeT++ message compiler. Remove your manual delete[] calls entirely—OMNeT++ handles dynamic array memory for you behind the scenes.
The correct auto-generated destructor (you don't need to write this manually; just let the message compiler regenerate it when you build your project) looks like this:
Msg_event_data::~Msg_event_data() { // The message compiler adds proper cleanup logic here automatically }
2. Follow OMNeT++'s Message Lifecycle Rules
OMNeT++ uses a reference-counting system for cMessage-derived objects (like your Msg_event_data). Here's how to correctly handle your messages:
- When creating and sending a message:
// Create the message (reference count starts at 1) Msg_event_data *msg = new Msg_event_data(); // Set message fields including dynamic arrays msg->setName_event_data("sensor_data"); msg->setClock(456); // Set dynamic array size and values int leftSize = 3; msg->setMap_left_columnArraySize(leftSize); for (int i = 0; i < leftSize; i++) { msg->setMap_left_column(i, i + 10); } // Send the message: OMNeT++ kernel increases the reference count and takes ownership send(msg, "out"); // DO NOT delete msg here! The kernel will handle cleanup after delivery - If you need to cancel a scheduled message:
If you've already sent the message but need to cancel it before it's delivered, use these steps to safely clean it up:if (msg->isScheduled()) { // Remove the message from the event heap first cancelEvent(msg); } // Decrement the reference count; the message will be deleted automatically when count reaches 0 msg->drop();
3. Avoid Manual Deletion of Scheduled Messages
Never call delete msg on a message that's been sent (and thus is in the cEventHeap). OMNeT++ will handle destroying the message once it's been processed by the receiving module.
Why This Works
OMNeT++'s message compiler generates code that properly manages dynamic arrays using its own memory system, which integrates with the simulation kernel's event management. By removing your manual delete[] calls and following the message lifecycle rules, you let the kernel handle object ownership, eliminating the conflict that caused your runtime error.
内容的提问来源于stack exchange,提问作者clementlari

