Access element of Vector

Dear all,

I use this code in my research,
1
2
3
4
5
6
7
8
9
10
11
12
13
vector<RoutingPacket> bufferAggregate;
class RoutingPacket: public::cPacket {}
class LeachRoutingPacket: public::RoutingPacket {}

void LeachRouting::fromMacLayer(cPacket *pkt, int macAddress, double rssi, double lqi)
{
     LeachRoutingPacket *netPacket = dynamic_cast <LeachRoutingPacket*>(pkt);
     ....
     ....
     if (isCH && dst.compare(SELF_NETWORK_ADDRESS) == 0) {
           bufferAggregate.push_back(*netPacket);
     }
}


I want to access the element of bufferAggregate in other void/method. Is it right if I write this
 
LeachRoutingPacket *lrpkt = dynamic_cast <LeachRoutingPacket*> (&bufferAggregate[i]);

Thank you for your help

elisati h.


Last edited on
No, `bufferAggregate' stores `RoutingPacket', it does not store `LeachRoutingPacket'. That cast will fail.
See `object slicing'
Tq for your response...

But in void LeachRouting::fromMacLayer(cPacket *pkt, int macAddress, double rssi, double lqi)
"pkt" has been cast in to LeachRoutingPacket *netPacket before push_back into bufferAggregate?
again, read about object slicing.
Ok. I see.
I read about object slicing. "Slicing means that the data added by a subclass are discarded when an object of the subclass is passed or returned by value or from a function expecting a base class object. As baseclass copy functions don't know anything about the derived only the base part of the derived is copied."

Do you mean, the buffer Aggregate [i] has no data element (e.g. from encapsulated packet) because suffered by object slicing?

tq
Ups... sorry.... this is the next my question

How to recover this problem. Because I want to access the element of data of the bufferAggregate[i]. I other method, element of bufferAggregate[i] has been assigned with data.

tq
Something like this:

1
2
3
4
5
6
7
8
9
10
11
12
std::vector<LeachRoutingPacket> bufferAggregate; // vector of LeachRoutingPackets

// ...

void LeachRouting::fromMacLayer( cPacket *pkt, int macAddress, double rssi, double lqi )
{
    LeachRoutingPacket *netPacket = dynamic_cast <LeachRoutingPacket*>(pkt);
    // ....
    // ....
    if( netPacket != nullptr && isCH && dst.compare(SELF_NETWORK_ADDRESS) == 0) {
           bufferAggregate.push_back(*netPacket); // append a copy of LeachRoutingPacket to the vector
}


And then: LeachRoutingPacket *lrpkt = &bufferAggregate[i];

Or preferably: LeachRoutingPacket& lrpkt = bufferAggregate[i];
when I write
 
LeachRoutingPacket *lrpkt = &bufferAggregate[i]; 

error: invalid conversion from 'RoutingPacket*' to 'LeachRoutingPacket*'

while, if I write this
 
LeachRoutingPacket& lrpkt = bufferAggregate[i];

error: invalid initialization of reference of type 'LeachRoutingPacket&' from expression of type 'RoutingPacket'

In the first my post, I have write this:

1
2
3
vector<RoutingPacket> bufferAggregate;
class RoutingPacket: public::cPacket{}
class LeachRoutingPacket: public::RoutingPacket{}


Last edited on
Change this:
1
2
// vector<RoutingPacket> bufferAggregate;
std::vector<LeachRoutingPacket> bufferAggregate; // vector of LeachRoutingPackets 
Solved for getting bufferAggregate[i].

But, this is the full code of fromMacLayer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class ApplicationPacket : public ::cPacket {};
void LeachRouting::fromMacLayer(cPacket *pkt, int macAddress, double rssi, double lqi)
{
     LeachRoutingPacket *netPacket = dynamic_cast <LeachRoutingPacket*>(pkt);
     ....
     ....
     if (isCH && dst.compare(SELF_NETWORK_ADDRESS) == 0) {
          // to access the encapsulated packet
          cPacket *pkt1;
          pkt1 = decapsulatePacket(netPacket);
          ApplicationPacket *appkt = dynamic_cast <ApplicationPacket*> (pkt1)
          // and then... success to get the data from the appkt.

           bufferAggregate.push_back(*netPacket);
     }
}

and then
in other method I want to access bufferAggregate[i] to get the data, like this code:
1
2
3
LeachRoutingPacket& lrpkt = bufferAggregate[i];
cPacket *pkt = decapsulatePacket(lrpkt);
ApplicationPacket *appkt = dynamic_cast <ApplicationPacket*> (pkt)

but have some error. What wrong in the last code?


Last edited on
> but have some error. What wrong in the last code?

What is that 'some error'?
It helps if you clearly state what the error is (provide the error diagnostic emitted by the compiler).

If line 10 of LeachRouting::fromMacLayer is right, then it should be:
1
2
3
4
LeachRoutingPacket& lrpkt = bufferAggregate[i];
// cPacket *pkt = decapsulatePacket(lrpkt);
cPacket *pkt = decapsulatePacket( std::addressof(lrpkt) ) ; // pass the pointer
ApplicationPacket *appkt = dynamic_cast <ApplicationPacket*> (pkt) ;
but fail in
 
cPacket *pkt = decapsulatePacket( std::addressof(lrpkt) ); 

pkt is NULL pointer


It would appear that decapsulatePacket returned nullptr;
perhaps (I'm guessing here) indicating that it was unable to de-encapsulate this particular packet.
I think so...

But Why??

In here, decapsulatePacket was success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class ApplicationPacket : public ::cPacket {};
void LeachRouting::fromMacLayer(cPacket *pkt, int macAddress, double rssi, double lqi)
{
     LeachRoutingPacket *netPacket = dynamic_cast <LeachRoutingPacket*>(pkt);
     ....
     ....
     if (isCH && dst.compare(SELF_NETWORK_ADDRESS) == 0) {
          // to access the encapsulated packet
          cPacket *pkt1;
          pkt1 = decapsulatePacket(netPacket);
          ApplicationPacket *appkt = dynamic_cast <ApplicationPacket*> (pkt1)
          // and then... success to get the data from the appkt.

           bufferAggregate.push_back(*netPacket);
     }
}

after bufferAggregate.push_back(*netPacket), the encapsulated packet is missing out?? whether this is called by "ne555" as a slicing object?
but NO... because
1
2
// vector<RoutingPacket> bufferAggregate;
std::vector<LeachRoutingPacket> bufferAggregate; // vector of LeachRoutingPackets 
There is no object-slicing of the object (may be sub-object) of type LeachRoutingPacket now.


> In here, decapsulatePacket was success

Verify that LeachRoutingPacket has correctly implemented copy and move constructors.
I add tracing code in the below of bufferAggregate.push_back(*netPacket)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ApplicationPacket : public ::cPacket {};
void LeachRouting::fromMacLayer(cPacket *pkt, int macAddress, double rssi, double lqi)
{
     LeachRoutingPacket *netPacket = dynamic_cast <LeachRoutingPacket*>(pkt);
     ....
     ....
     if (isCH && dst.compare(SELF_NETWORK_ADDRESS) == 0) {
          // to access the encapsulated packet
          cPacket *pkt1;
          pkt1 = decapsulatePacket(netPacket);
          ApplicationPacket *appkt = dynamic_cast <ApplicationPacket*> (pkt1)
          // and then... success to get the data from the appkt.

           bufferAggregate.push_back(*netPacket);
           // just for trace
           for (int i=0; i < bufferAggregate.size(); i++) {
                LeachRoutingPacket *lpkt = (&bufferAggregate[i]);
                printf("has encapsulated packet %d ", lpkt->hasEncapsulatedPacket());
           }
     }
}


result: 1 for index=0; 0 for index: 1, 2, ... (waow... why??). Missing out in the bufferAggregate??
I think, we have add additional code, to encapsulate pkt into netPacket, before push_back into bufferAggregate, like this code below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class ApplicationPacket : public ::cPacket {};
void LeachRouting::fromMacLayer(cPacket *pkt, int macAddress, double rssi, double lqi)
{
     LeachRoutingPacket *netPacket = dynamic_cast <LeachRoutingPacket*>(pkt);
     ....
     ....
     if (isCH && dst.compare(SELF_NETWORK_ADDRESS) == 0) {
    
          LeachRoutingPacket *netPacketData = new LeachRoutingPacket();
          // to access the encapsulated packet
          cPacket *pkt1;
          pkt1 = decapsulatePacket(netPacket);
          ApplicationPacket *appkt = dynamic_cast <ApplicationPacket*> (pkt1)
          // and then... success to get the data from the appkt.
            
           encapsulatePacket(netPacketData, pkt1); // 
           bufferAggregate.push_back(*netPacketData);
     }
}
> result: 1 for index=0; 0 for index: 1, 2, ... (waow... why??)

1. Verify that LeachRoutingPacket has correctly implemented copy and move constructors.

2. Verify that the packet pointed to by netPacket is not modified during this operation:
// and then... success to get the data from the appkt.

3. Modify the code as follows and run it. What are the results?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void LeachRouting::fromMacLayer(cPacket *pkt, int macAddress, double rssi, double lqi)
{
    // omit the const in the following line if the API does not permit it
    const LeachRoutingPacket *netPacket = dynamic_cast < const LeachRoutingPacket* >(pkt);

    if(netPacket) printf( "1. after dynamic cast, netPacket has encapsulated packet %d ", netPacket->hasEncapsulatedPacket() ) ;
    ....
    ....
    if ( netPacket && isCH && dst.compare(SELF_NETWORK_ADDRESS) == 0) {

        // to access the encapsulated packet
        cPacket *pkt1;
        pkt1 = decapsulatePacket(netPacket);
        ApplicationPacket *appkt = dynamic_cast <ApplicationPacket*> (pkt1)
        // and then... success to get the data from the appkt.

        printf( "2. after get data from the appkt, netPacket has encapsulated packet %d ", netPacket->hasEncapsulatedPacket() ) ;

        bufferAggregate.push_back(*netPacket);
        printf( "3. after push_back, copy in the vector has encapsulated packet %d ", bufferAggregate.back().hasEncapsulatedPacket() ) ;
    }
}
eureka...

this code, changing *netPacket (remove the encapsulated packet).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void LeachRouting::fromMacLayer(cPacket *pkt, int macAddress, double rssi, double lqi)
{
        ....
        ...
       if ( netPacket && isCH && dst.compare(SELF_NETWORK_ADDRESS) == 0) {

        // I HAVE REMOVED THIS CODE and SOLVED
       // to access the encapsulated packet
        cPacket *pkt1;
        pkt1 = decapsulatePacket(netPacket);
        ApplicationPacket *appkt = dynamic_cast <ApplicationPacket*> (pkt1)
        // and then... success to get the data from the appkt.

       }
}


Thank you so much JLBorges (10026), you make me, found my wrong :) :)
Last edited on
Topic archived. No new replies allowed.