c ++ void *内存遍历

时间:2013-10-30 01:23:29

标签: c++ memory-management void-pointers

我正在尝试使用void *&存储内存中的几个整数。然后检索它们但它不断抛出“在算术中使用的类型'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位数字。

3 个答案:

答案 0 :(得分:3)

a+2a是指针,意味着指针增加以允许两个指针类型的空间。例如,如果aint32 *a + 2将表示“一个位置加上8个字节”。

由于void *没有类型,因此它只能尝试猜测a + 2的含义,因为它不知道所引用类型的大小。

答案 1 :(得分:2)

问题是编译器不知道如何处理

a+2

此指令的意思是“将指针''向前移动2 *(sizeof-what-that-to-to-by-'a')”。

如果a是void *,编译器不知道目标对象的大小(没有一个!),所以它会出错。

你需要这样做:

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

这样,编译器知道如何添加2 - 它知道sizeof(char)

答案 2 :(得分:0)

  

如果我错了,请纠正我,但根据我的理解,使用char *而不是void *会占用3位数的3个字节。

是的,你错了,如果你把这些数字作为字符传输的话就是这种情况。 'char *'只是一种引用8位值的便捷方式 - 由于您接收的是字节对,因此您可以将目标内存视为char来进行简单的数学运算。但是人们使用'char'数组来表示网络数据流是相当普遍的。

我更喜欢使用类似BYTEuint8_t的内容来清楚地表明'我正在使用字节'而不是字符或其他值。

void*是指向未知的,更重要的是0大小类型(void)的指针。因为大小为零,偏移数学将导致零,所以编译器告诉你它是无效的。

您的解决方案可能就像从网络接收字节到基于字节的数组一样简单。 int是32位,4个字节。它们不是“char”值,而是4字节整数的四边形。

#include <cstdint>

uint8_t buffer[4];

一旦你知道你已填满缓冲区,你可以简单地说

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

这是否正确将取决于字节是网络还是主机顺序。我猜你可能需要:

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