我正在尝试使用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位数字。
答案 0 :(得分:3)
a+2
,a
是指针,意味着指针增加以允许两个指针类型的空间。例如,如果a
为int32 *
,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'数组来表示网络数据流是相当普遍的。
我更喜欢使用类似BYTE
或uint8_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)));