我只是不知道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;
}
Run Code Online (Sandbox Code Playgroud)
输出:0000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000010000000000000000000000010000000
64 92
数字应该只是100 120,但它们不是!
我相信你有一个关于字节序的问题.当你将缓冲区转换为a时,uint64_t你将缓冲区转换为一个小尾数uint64_t.因此,您的字节将按如下顺序排序:
即.
buffer: | char 0 | char 1 | char 2 | ... | char n
uint64_t: | byte 8 | byte 7 | byte 6 | ... | byte 0
Run Code Online (Sandbox Code Playgroud)
然后,您将此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])
Run Code Online (Sandbox Code Playgroud)
但是,如果您尝试在大端机器上使用代码,这将给您带来问题.
实际上,更好的方法是使用:
#define to_uint64(buffer,n) (*(uint64_t*)(buffer + n))
Run Code Online (Sandbox Code Playgroud)
编辑:我改变了上面的宏,因为caf指出我不需要a a uint64_tto a uint64_t.宏的工作方式是将缓冲区指针(unsinged char *)转换为uint64_t指针,然后取消引用它.