2011-09-26 57 views
0

我想要或两个大块的内存......但它不起作用内存块之间的逻辑运算?

考虑我有三个char * bm,bm_old和bm_res。

#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];} 

... 

for (unsigned int i=0; i<bitmapsize(size)/8; i++){ 
     uint64_t or_res = (to_uint64(bm_old,i*8)) | (to_uint64(bm,i*8)); 
     memcpy(bm_res+i*sizeof(uint64_t), &or_res, sizeof(uint64_t)); 
} 

bm_res不正确!

有什么线索?

谢谢,

埃米尔。

+0

为什么不简单地'reinterpret_cast'缓冲区? –

+0

@ K-ballo,严格来说这是未定义的行为。但它也比这更简单也可能更快... – bdonlan

+0

@ K-ballo:那会是UB。 –

回答

3

将括号to_uint64的定义括在括号()而不是大括号{}中,并在最后删除分号。使用#define可创建一个宏,其文本逐字地插入,而不是实际的函数,因此您试图使用| - 共两个块,而不是那些块的“返回值”。

+0

我相信这将是正确的代码! (uint64_t)buffer [n] << 56 |(uint64_t)buffer [n + 1] << 48 |(uint64_t)buffer [n + 2] << 40 |(uint64_t)#define to_uint64(buffer,n) )buffer [n + 3] << 32 |(uint64_t)buffer [n + 4] << 24 |(uint64_t)buffer [n + 5] << 16 |(uint64_t)buffer [n + 6] << 8 | (uint64_t中)缓冲液[N + 7]) ... 为(无符号整数,I = 0; I Amir

2

我认为你需要通过正确的尺寸来为自己的输出指针:

memcpy(bm_res + i * sizeof(uint64_t), &or_res, sizeof(uint64_t)); 
       ^^^^^^^^^^^^^^^^^^^^ 

由于bm_res是一个字符指针,+ 1垫款只是一个字节。

+0

是啊,你是对的! – Amir

2

对于移动的每个八字节块,您正在将bm_res增加1。此外,您永远不会增加bmbm_old。所以你基本上在bm_res上平铺or_res的第一个字节,这可能不是你想要的。

更重要的是,您的代码对字节顺序敏感 - 无论是or_res在内存中表示为最小顺序字节的第一个还是最高顺序的第一个问题。

我会建议你只做一个字节的字节或第一,并且只尝试优化它,如果这太慢。当你优化它时,不要在那里使用你疯狂的to_uint64宏 - 它会比逐字节地慢。相反,直接投射到uint64_t *。严格地说,这是未定义的行为,它适用于我见过的每个平台,并且应该是字节顺序不可知的。

+0

我知道..我在想什么! – Amir