SlimDeluxe
SlimDeluxe

Reputation: 838

In C++, passing a pointer still copies the object?

I've been reading for an hour now and still don't get what is going on with my application. Since I am using instances of object with new and delete, I need to manage the memory myself. My application needs to have long uptimes and therefore properly managing the memory consumption is very crucial for me.

Here's the static function I use to dump the datapacket, which is transfered between a PC and the I/O board in both directions. The datapacket is an array of BYTEs and is encapsulated into an object, either DCCmd or DCReply (both are implementation of an abstract DCMessage class).

void DebugTools::dumpBytes(BYTE* bytes, short length)
{
    printf("       |---DUMPING DATAPACKET refId: %d ....\n", &bytes);
    for(short i=0; i<length; i++){
        printf("       | B%d | %.2X\n", i, bytes[i]);
    }
    printf("       |---END DUMP           refId: %d ....\n", &bytes);
}

Then there's this use case: I create a DCCmd object and add it to the outgoing message queue to be sent. The "pump" (an infinite loop) checks the outbox and passes any candidates to a IOConnector singleton object.

DCCmd* cmd = new DCCmd(DIG_CMD_SELFTEST_RES);
cmd->add(param);
printf("cmdSelfTest()\n"); //HACK
BYTE* cmda = cmd->getBytes(); //HACK
DebugTools::dumpBytes(cmda, cmd->getLength()); //HACK
sendMsg(cmd);

... and adding to the queue:

bool DC::sendMsg(DCMessage* msg)
{
    if(isOnline()){
        outbox->add(msg);
        return true;
    } else {
        return false;
    }
}

Adding to the queue is done with void add(DCMessage* msg);

(In the connector class there's another of those dumpBytes() to see what is really going to be sent)

But here's the output:

TESTING MESSAGE QUEUES ....
cmdSelfTest()
       |---DUMPING DATAPACKET refId: 2489136 ....
       | B0 | C6
       | B1 | A1
       | B2 | 00
       | B3 | 01
       | B4 | 10
       | B5 | 00
       | B6 | 01
       | B7 | 78
       |---END DUMP           refId: 2489136 ....
    adding to queue: 2488884
   queues: inbox (0), outbox (1)
send: sending candidates....
  sending 2489164 ....
    >->-> ...
       |---DUMPING DATAPACKET refId: 2488704 ....
       | B0 | C6
       | B1 | A1
       | B2 | 00
       | B3 | 01
       | B4 | 10
       | B5 | 00
       | B6 | 01
       | B7 | 78
       |---END DUMP           refId: 2488704 ....
Packet sent!
. ((second iteration of the pump))
   queues: inbox (0), outbox (1)
send: sending candidates....
  sending 2489164 ....
    >->-> ...
       |---DUMPING DATAPACKET refId: 2488704 ....
       | B0 | C6
       | B1 | A1
       | B2 | 00
       | B3 | 01
       | B4 | 10
       | B5 | 00
       | B6 | 01
       | B7 | 78
       |---END DUMP           refId: 2488704 ....
Packet sent!

Can someone please shed some light why the references are different each time I pass from one block to the other? What does this mean to the memory consumption? How can I make sure I am not duplicating memory? Thanks.

Upvotes: 2

Views: 540

Answers (3)

Pete
Pete

Reputation: 12573

The variable bytes is the pointer to the data, i.e. the memory location of the data. But that is not what you are printing, you are printing out the address where this pointer is located, i.e. the address on the stack where the pointer is passed. So

printf("       |---DUMPING DATAPACKET refId: %d ....\n", &bytes);

should just be

printf("       |---DUMPING DATAPACKET refId: %d ....\n", bytes);

Upvotes: 5

Glen
Glen

Reputation: 22300

In your calls to dumpBytes you passed the bytes using pass-by-copy instead of pass-by-reference.

This results in a new pointer to BYTES being created for the lifetime of the dumpBytes. Depending on your system this will be 8,16,32,64 bytes etc. In otherwords, unless you've got really, really tight memory constraints then it's not an issue.

Upvotes: 1

Arkaitz Jimenez
Arkaitz Jimenez

Reputation: 23198

The bytes variable is a function parameter in dumpBytes, in this case a pointer, you get a new pointer copied from the passed pointer, but it is still a new one, with his own address in the stack, so taking its address is going to be different every time, unless it is called from the same place and the stack addresses result in the same by pure coincidence.

Upvotes: 1

Related Questions