2009-09-22 50 views
2

我一直在閱讀一個小時,仍然沒有得到我的應用程序正在發生什麼。 由於我使用newdelete的對象實例,我需要自己管理內存。我的應用程序需要很長的正常運行時間,因此正確管理內存消耗對我來說非常重要。在C++中,傳遞指針仍然會複製對象?

這是我用來轉儲datapacket的靜態函數,它在PC和I/O板之間在兩個方向上傳輸。數據包是一個​​的數組,並被封裝到一個對象中,或者是DCCmd或者DCReply(都是抽象DCMessage類的實現)。

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); 
} 

再有就是這個用例:我創建了一個DCCmd對象,並將其添加到傳出消息隊列進行發送。 「泵」(一個無限循環)檢查發件箱並將任何候選人傳遞給一個IOConnector單身物件。

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); 

...並添加到隊列:

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

添加到隊列與void add(DCMessage* msg);

完成(在連接器類有另一個這些dumpBytes(),看看什麼是真正將被髮送)

但是,這裏的輸出:

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! 

有人可以請一些光爲什麼每次我從一個塊傳遞到另一個時,引用是不同的?這對內存消耗意味着什麼?我怎樣才能確保我沒有複製內存?謝謝。

回答

5

變量字節是指向數據的指針,即數據的內存位置。 但是,這不是你正在打印的內容,你正在打印出這個指針所在的地址,即指針被傳遞到堆棧上的地址。所以

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

應該只是

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

事實上,在我檢查我是否使用同一陣列副本時修改了這一點以及所有的出現,在整個應用程序中輸出了相同的地址。指針實際上按預期工作,非常棒! – 2009-09-22 09:47:15

1

字節變量是dumpBytes函數參數,在這種情況下指針,你從通過指針複製一個新的指針,但它仍然是一個新的,用他自己的地址在棧,所以取其地址每次都會有所不同,除非它被從同一個地方調用,堆棧地址由純粹的巧合導致相同。

+0

我已經添加了泵的第二次迭代,所以注意如何在第二次的值是相同的。所以我想這不是每一次,它都必須在某個地方儲存一些東西,以便發生這種情況。 – 2009-09-22 09:36:36

+0

它更可能只是在堆棧上的相同位置。 – Kylotan 2009-09-22 09:43:36

+0

哦,我承認我並不完全熟悉堆棧和所有=) – 2009-09-22 09:55:47

1

在對dumpBytes的調用中,您使用pass-by-copy而不是pass-by-reference來傳遞字節。

這會產生一個新的指針以便在dumpBytes的生命週期中創建BYTES。根據你的系統,這將是8,16,32,64字節等。換句話說,除非你真的有非常嚴格的內存限制,那麼這不是問題。

+0

我想知道主要關於BYTE陣列內存消耗,而不是指針。 – 2009-09-22 09:38:12

+0

@Omer,唯一被複制的是指向數組的指針,而不是數組本身 – Glen 2009-09-22 11:09:08

+0

是的,我現在明白你的觀點。所以人們會猜測指針在超出作用域時也會自動釋放,就像我的dumpBytes()函數中的字節一樣? – 2009-09-22 19:59:18