我只是不知道memcpy的工作原理。您只需复制粘贴代码,看看输出如何不加起来。我知道我可以用其他方式编写代码,但我只是想知道为什么memcpy不起作用。
typedef unsigned char* bitmap;
#define getbit(n,bmp) ((bmp[(n)>>3])&(0x80>>((n)&0x07)))
#define setbit(n,bmp) {bmp[(n)>>3]|=(0x80>>((n)&0x07));}
#define bitmapsize(n) (((int)(n)+7)>>3)
#define to_uint64(buffer,n) ((uint64_t)buffer[n] << 56 | (uint64_t)buffer[n+1] << 48 | (uint64_t)buffer[n+2] << 40 | (uint64_t)buffer[n+3] << 32 | (uint64_t) buffer[n+4] << 24 | (uint64_t)buffer[n+5] << 16 | (uint64_t)buffer[n+6] << 8 | (uint64_t)buffer[n+7])
int main(int argc, char *argv[])
{
bitmap bm1, bm2,bm3;
unsigned int m_size=128;
if (!(bm1 = (bitmap) calloc (bitmapsize(m_size), sizeof(char))));
setbit(100,bm1);
if (!(bm2 = (bitmap) calloc (bitmapsize(m_size), sizeof(char))));
setbit(120,bm2);
for (unsigned int i = 0; i < bitmapsize(m_size)/sizeof(uint64_t); i++)
{
uint64_t or_res = (to_uint64(bm2, i * sizeof(uint64_t))) | (to_uint64(bm1, i * sizeof(uint64_t)));
std::cout<<std::bitset<64>(or_res)<<" ";
memcpy(bm1 + i * sizeof(uint64_t), &or_res, sizeof(uint64_t));
}
for (int i=0; i<m_size;i++)
if (getbit(i,bm1)) std::cout<<i<<" ";
std::cout<<std::endl;
free(bm1);
free(bm2);
return 0;
}
输出: 0000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000010000000000000000000000010000000
64 92
数字应该只是100 120,但它们不是!
答案 0 :(得分:6)
我相信你有一个关于字节序的问题。当您将缓冲区转换为uint64_t
时,您将缓冲区转换为小端uint64_t
。因此,您的字节将按如下顺序排序:
即
buffer: | char 0 | char 1 | char 2 | ... | char n
uint64_t: | byte 8 | byte 7 | byte 6 | ... | byte 0
然后你将这个uint64_t直接复制到你的缓冲区中,这样你的字节就被错误地排序了。
最简单的解决方法是更改to_uint64
宏:
#define to_uint64(buffer,n) ((uint64_t)buffer[n+7] << 56 | (uint64_t)buffer[n+6] << 48 | (uint64_t)buffer[n+5] << 40 | (uint64_t)buffer[n+4] << 32 | (uint64_t) buffer[n+3] << 24 | (uint64_t)buffer[n+2] << 16 | (uint64_t)buffer[n+1] << 8 | (uint64_t)buffer[n])
但是,如果您尝试在大端机器上使用代码,这将给您带来问题。
实际上,更好的方法是使用:
#define to_uint64(buffer,n) (*(uint64_t*)(buffer + n))
编辑:我更改了上面的宏,因为caf指出我不需要将uint64_t
置于uint64_t
。宏的工作方式是将缓冲区指针(unsinged char *
)转换为uint64_t
指针,然后取消引用它。