2013-10-30 24 views
0

我試圖在內存中使用void * &來存儲一些int,然後檢索它們,但它一直拋出「在算術中使用類型'void *'的指針」警告。C++ void *內存遍歷

void *a = new char[4]; 
memset(a, 0 , 4); 


unsigned short d = 7; 
memcpy(a, (void *)&d, 2); 

d=8; 
memcpy(a+2, (void *)&d, 2); //pointer of type ‘void *’ used in arithmetic 


/*Retrieving*/ 
unsigned int *data = new unsigned int(); 
memcpy(data, a, 2); 
cout << (unsigned int)(*data); 

memcpy(data, a+2, 2); //pointer of type ‘void *’ used in arithmetic 
cout << (unsigned int)(*data); 

結果符合預期,但我擔心這些警告可能會在某些編譯器中變成錯誤。有沒有另一種方法可以做到這一點,我不知道?

我知道這在正常情況下可能是不好的做法,但問題陳述要求無符號整數以2字節數據包的形式存儲和發送。如果我錯了,請糾正我,但根據我的理解,使用char *而不是void *會佔用3個字節的3位數字。

+2

你爲什麼要'void *'?你可以使用'char *' –

+0

new運算符動態分配內存,所以不需要memset。對於通用數據類型,C++也有模板。 –

+0

我需要二進制數據,以便無符號整數存儲在2個字節中。我猜char *需要3個字節的3位數字? – mindreader

回答

2

的問題是,編譯器不知道如何處理

a+2 

該指令做指「2 *移動指針‘一’前(的sizeof - 什麼 - 是尖到由-'一個')」。

如果a是void *,編譯器不知道目標對象的大小(沒有一個!),所以它會給出錯誤。

你需要做的:

memcpy(data, ((char *)a)+2, 2); 

這樣,編譯器知道如何添加2 - 它知道sizeof(char)

3

a+2,其中a是一個指針,意味着指針增加以允許指針類型的兩個項目的空間。例如,如果aint32 *,a + 2將意味着「位置加8字節」。

由於void *沒有類型,它只能嘗試猜測你的意思是a + 2,因爲它不知道被引用類型的大小。

+0

感謝您的回覆。我確實對+ 2內存位置感興趣。如何訪問? – mindreader

+1

將'a'強制轉換爲一個字節大小的指針(或者一個雙字節大小的指針,但是隻加上'1')。明顯的選擇是'char',但它的實際大小取決於平臺,因此請檢查它。 – SJuan76

+2

@mindReader'a + 2(what ???)'2個字節?您需要明確指出,'char'和'int'類型佔用不同的內存空間,因此它通過指針運算來反映! –

0

請糾正我,如果我錯了,但根據我的理解,使用char *而不是void *會佔用3個字節的3位數字。

是的,你錯了,如果你將這些數字作爲字符傳輸,情況就是這樣。 'char *'只是提供8位值的一種方便的方式 - 而且由於您正在接收字節對,因此您可以將目標內存用char來進行簡單的數學運算。但是對於網絡數據流使用'char'數組的人來說是相當普遍的。

我更喜歡使用類似​​或uint8_t的東西來清楚地表明'我正在處理字節'而不是char或其他值。

void*是指向未知,更重要的是0大小的類型(void)的指針。由於大小爲零,因此偏移數學將導致零,因此編譯器會告訴您這是無效的。

您的解決方案可能很簡單,只需將網絡中的字節接收到基於字節的數組中即可。一個int是32位,4個字節。它們不是「char」值,而是四字節整數的四元組。

#include <cstdint> 

uint8_t buffer[4]; 

一旦你知道你已經填寫的緩衝區,你可以簡單地說

uint32_t integer = *(static_cast<uint32*>(buffer)); 

這是否是正確的,將取決於字節是否在網絡或主機的命令。我猜你可能需要:

uint32_t integer = ntohl(*(static_cast<uint32*>(buffer)));