內存的三種分配方式:
1. 從靜態存儲區分配:此時的內存在程序編譯的時候已經分配好,并且在程序的整個運行期間都存在。全局變量,static變量等在此存儲。
2. 在棧區分配:相關代碼執行時創建,執行結束時被自動釋放。局部變量在此存儲。棧內存分配運算內置于處理器的指令集中,效率高,但容量有限。
3. 在堆區分配:動態分配內存。用new/malloc時開辟,delete/free時釋放。生存期由用戶指定,靈活。但有內存泄露等問題。
為什么會說這個東西,平時沒有感覺,但是最近做制定通信協議時,一時沒有考慮清楚,然后不斷測試顯示錯誤。通過內存查看,發現他們是不同的存儲模塊,發送時,只是把棧上的數據發送成功,堆上的數據全部回收了。
具體例子如下:
struct test
{UINT16 cmd;UINT16 uDataLength;char* pData;test(int nLen){pData = new char(nLen);cmd = 1;uDataLength = sizeof(test) + nLen;}void SetData(const char* pBuf){memcpy(pData, pBuf, strlen(pBuf);}
}
創建的時候我用的是棧test obj, 然后傳入堆上面的數據,本地使用是沒有問題的,但是tcp傳送后,就只能解析到頭cmd和數據長度,具體數據全部感覺丟失了,但是這個問題,tcp內網又不會出現丟數據問題,所以還是自己程序問題,然后就開始查看內存分配,突然間就想到一個問題,這個東西不是同一個東西,不是連續的空間,數據發送時,堆上的數據就已經隨著堆得回收全部回收了。所以呢。
我的主要目的是什么呢:我的主要應用是想用結構體的字節頭來獲取后面協議的cmd和datalength所以,我需要全部自己序列化,要不就是全部在同一個連續內存中。
具體就是全部在堆上如何表現: 我有一個結構體頭,還有一個協議體protobuf,所以需要創建一個連續內存,比如說char* pData = new char(100);
然后就是先把結構體頭memcpy到pData中,然后連續copyprotobuf到pData中。最后發出pData即可!
寫此文,重點提醒一下自己!
轉載自:https://blog.csdn.net/u012307430/article/details/51648419