Omnet++,即将抛出cRuntimeError异常

Omnet++, A cRuntimeError exception is about to be thrown

我目前正在使用 Omnet++ 和 veins,突然出现这个运行时错误,我无法理解它以便正确修复它。

Error in module (TraCIDemoRSU11p) RSUExampleScenario.rsu[0].appl (id=8) at event #6180, t=53.956510612297: Array of size 220 indexed by 220. TRAPPING on the exception above, due to a debug-on-errors=true configuration option. Is your debugger ready?

我假设它可能与我使用此代码从 RSU 发送到车辆的这条消息有关,但我不确定它是如何相关的。

cplusplus {{
#include "veins/modules/messages/WaveShortMessage_m.h"

}}
class WaveShortMessage;


message DelayedFromControllerMessage extends WaveShortMessage {
    string vehiclesList [220] ;

}

我正在使用 omnet++ 版本:5.0 和 Veins 4.4

已编辑,我在这些地方使用数组:

1-

void TraCIDemoRSU11p::sendDelayedMessage(std::list<const char *> vehicleList) {
    sentDelayedMessage = true;
    //vehicleList = {};
    t_channel channel = dataOnSch ? type_SCH : type_CCH;
    DelayedFromControllerMessage* dsm = prepareDelayedSM("delayed",dataLengthBits, channel, dataPriority, -1,2,vehicleList);

    std::list<const char *>::iterator it = vehicleList.begin();
    //const char * v;
    char* vx = new char [100];
    vx[0] = '[=11=]';
    for(int i=0; i<vehicleList.size(); i++){
        //v =*it;
        strcpy(vx,*it);
        //vx = *it;
        ++it;
        dsm->setVehiclesList(i, vx);
     }
    if (sendDelayedEvt->isScheduled()) {
        cancelAndDelete(sendDelayedEvt);
    }else {
        delete sendDelayedEvt;
    }
    sendDelayedEvt = new cMessage("delayed evt", SEND_DELAYED_EVT); // create event object to use it in timing

    simtime_t offSet = dblrand() * (par("beaconInterval").doubleValue());
    TimeStart = simTime() + offSet;
    scheduleAt(TimeStart, sendDelayedEvt);
    sendDelayedSM(dsm);

}

2-

DelayedFromControllerMessage*  BaseWaveApplLayer:: prepareDelayedSM(const char * name, int lengthBits, t_channel channel, int priority, int rcvId,int serial,std::list<const char *>vehicleList ) {
    DelayedFromControllerMessage* dsm =       new DelayedFromControllerMessage(name);

    dsm->addBitLength(headerLength);
    dsm->addBitLength(lengthBits);

    switch (channel) {
        case type_SCH: dsm->setChannelNumber(Channels::SCH1); break; //will be rewritten at Mac1609_4 to actual Service Channel. This is just so no controlInfo is needed
        case type_CCH: dsm->setChannelNumber(Channels::CCH); break;
    }

    dsm->setPsid(0);
    dsm->setPriority(priority);
    dsm->setWsmVersion(1);
    dsm->setTimestamp(simTime());
    dsm->setSenderAddress(myId);
    dsm->setRecipientAddress(rcvId);
    dsm->setSenderPos(curPosition);
    dsm->setSerial(serial);



    std::list<const char *>::iterator it = vehicleList.begin();
    const char * v;

       for(int i=0; i<vehicleList.size(); i++){
           v =*it;
           ++it;
           VLvar1.push_back(v);
           dsm->setVehiclesList(i, v);
       }



    if ((std::string)name == "beacon") {
        DBG << "Creating Beacon with Priority " << priority << " at Applayer at " << dsm->getTimestamp() << std::endl;
    }
    if ((std::string)name == "delayed") {
        DBG << "Creating Data with Priority " << priority << " at Applayer at " << dsm->getTimestamp() << std::endl;
    }

    return dsm;
}

3-

void MyTraCIDemo11p::onDataDelayed(DelayedFromControllerMessage* dsm) {
    int x = 0;
    std::string vehichleId = mobility->getExternalId();

        for (int i=0 ; i < dsm->getVehiclesListArraySize();i++)
        {
            vehicleList.push_back(std::string(dsm->getVehiclesList(i)));

        }


        ttry = std::find(vehicleList.begin(), vehicleList.end(), vehichleId);
        if (vehichleId == *ttry){
            x = 1;
        }


        if (state == QUEUING  && x == 1){
            findHost()->bubble("Received ");
             state = WAITING;
             stateToString(state);
        }
}

消息应从 RSU 发送到车辆。

即使没有看到来自应用程序 (appl) 或您正在使用的配置文件的实际代码,我猜您正在尝试从数组中获取最后一个元素(元素 220)。

错误消息已经说明了问题所在。您的数组大小为 220,您正尝试使用索引 220,这是不可能的,因为数组索引从 0 开始。因此,要寻址数组中的最后一个元素,您必须使用索引 221。

我不确定这是否是您出错的原因:

ttry = std::find(vehicleList.begin(), vehicleList.end(), vehichleId);
    if (vehichleId == *ttry){
        x = 1;
    }

但是,最好这样写:

    if (std::find(vehicleList.begin(), vehicleList.end(), vehichleId) !=  vehicleList.end()){
        x = 1;
    }

如果找不到,我不建议引用 find 迭代器(即 *ttry),就像引用 *(vehicleList.end()) 一样。

在我看来你有两个 veichleList 变量,一个是 dsm 中的数组,另一个是向量。这个对吗?如果是,您应该确保 veichleList.size() 始终小于或等于 220。

查看本教程以了解如何在 omnet++ 中调试项目: https://docs.omnetpp.org/tutorials/tictoc/part2/

所以我刚刚找到了解决这个问题的方法。

是这样做的:

cplusplus {{
#include "veins/modules/messages/WaveShortMessage_m.h"

}}
class WaveShortMessage;


message DelayedFromControllerMessage extends WaveShortMessage {
    string vehiclesList [] ;

}

=====

DelayedFromControllerMessage*  BaseWaveApplLayer:: prepareDelayedSM(const char * name, int lengthBits, t_channel channel, int priority, int rcvId,int serial,std::list<const char *>vehicleList ) {
DelayedFromControllerMessage* dsm =       new DelayedFromControllerMessage(name);

dsm->addBitLength(headerLength);
dsm->addBitLength(lengthBits);

switch (channel) {
    case type_SCH: dsm->setChannelNumber(Channels::SCH1); break; //will be rewritten at Mac1609_4 to actual Service Channel. This is just so no controlInfo is needed
    case type_CCH: dsm->setChannelNumber(Channels::CCH); break;
}

dsm->setPsid(0);
dsm->setPriority(priority);
dsm->setWsmVersion(1);
dsm->setTimestamp(simTime());
dsm->setSenderAddress(myId);
dsm->setRecipientAddress(rcvId);
dsm->setSenderPos(curPosition);
dsm->setSerial(serial);


int NS = 0;
std::list<const char *>::iterator itPD = vehicleList.begin();
const char * vPD;
int i0 = 0;
while(itPD != vehicleList.end()){
    vPD = *itPD;
    ++itPD;
    ++NS;
    dsm->setVehiclesListArraySize(NS);
    dsm->setVehiclesList(i0, vPD);
    ++i0;
    VLvar1.push_back(vPD);

}

if ((std::string)name == "beacon") {
    DBG << "Creating Beacon with Priority " << priority << " at Applayer at " << dsm->getTimestamp() << std::endl;
}
if ((std::string)name == "delayed") {
    DBG << "Creating Data with Priority " << priority << " at Applayer at " << dsm->getTimestamp() << std::endl;
}

return dsm;
}

我删除了数组大小,并使用 while 循环在 BaseWaveApplLayer::prepareDelayedSM 中放置了一个手动计数器。当遇到类似问题时,我考虑过发布解决方案以帮助其他人。 :)