返回信息流effictive c++,条款50
static const int signatre = 0xDEADBEEF;
...
...
void * pMem = malloc(realSize);
...
*(static_cast<int*>pMem)) = signature;
*(reinterpret_cast<int*>
(static_cast<Byte*>
(pMem)+realSize-sizeof(int)
)
) = signature;
...
...
若将reinterpret_cast<int*>改为static_cast<int*>是否结果一样?
reinterpret_cast的出现是为了防止字边界对齐而造成溢出?
这是一条镜像帖。来源:北邮人论坛 / cpp / #71969同步于 2013/6/20
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
以下语句reinterpret_cast的作用
chen24828393
2013/6/20镜像同步6 回复
订阅后,新回复会通过你的通知中心匿名送达。
6 条回复
改成static_cast是可以的,另外改了以后就不需要:
static_cast(Byte*>(pMem)+realSize-sizeof(int)
这样调整指针位置了~实际上static_cast与reinterpret_cast的主要区别就在于它会根据赋予指针的值得数据结构来调整指针的位置;比如你malloc了8个字节,实际赋予的就是一个int,这时候这个指针如果用reinterpret_cast来处理就是不安全的~开始的4个字节被按字节拷贝了数据,后边就是不安全的空余字节。
而用static_cast<type*>这样就相当于你上边的那个写法~编译器会帮你做字节对齐到结尾,将指针调整到字节起始位置,并将其到结尾处填满~
【 在 chen24828393 的大作中提到: 】
: effictive c++,条款50
: static const int signatre = 0xDEADBEEF;
: ...
: ...................
改了之后为什么不需要:
static_cast(Byte*>(pMem)+realSize-sizeof(int)
上诉代码的作用是在最后sizeof(int)个字节内写入签名,不要这条语句岂不是在分配的内存开头写入签名?
【 在 tonyjansan 的大作中提到: 】
: 改成static_cast是可以的,另外改了以后就不需要:
: static_cast(Byte*>(pMem)+realSize-sizeof(int)
: 这样调整指针位置了~实际上static_cast与reinterpret_cast的主要区别就在于它会根据赋予指针的值得数据结构来调整指针的位置;比如你malloc了8个字节,实际赋予的就是一个int,这时候这个指针如果用reinterpret_cast来处理就是不安全的~开始的4个字节被按字节拷贝了数据,后边就是不安全的空余字节。
: ...................
再ubuntu下测试了一下
使用语句static_cast替换reinterpret_cast:
*(static_cast<unsigned int*>(static_cast<Byte*>(pMem) + realsize-sizeof(int))) = signature;
gdb调试内存为
0x602010: 0xdeadbeef 0x00000000 0x00000000 0x00000000
0x602020: 0x00000000 0x00000000 0x00000000 0x00000000
0x602030: 0x00000000 0x00000000 0x00000000 0x00000000
0x602040: 0x00000000 0x00000000 0x00000000 0x00000000
0x602050: 0x00000000 0x00000000 0x00020fb1 0x00000000
0x602060: 0x00000000 0x00000000 0x00000000 0x00000000
0x602070: 0x00000000 0x00000000 0x00000000 0x00000000
0x602080: 0x00000000 0x00000000 0x00000000 0x00000000
0x602090: 0x00000000 0x00000000 0x00000000 0x00000000
0x6020a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x6020b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x6020c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x6020d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x6020e0: 0x00000000 0x00000000 0xdeadbeef 0x00000000
我申请的主空间值为50,加上两个签名,共58个字节,符合。
与reinterpret_cast转换,在内存上保持一致,唯一的区别是static_cast转化要写(unsigned int*)。
而若按你说的去掉位移,语句如下:
*(static_cast<unsigned int*>(static_cast<Byte*>(pMem))) = signature;
0x602060: 0xdeadbeef 0x00000000 0x00000000 0x00000000
0x602070: 0x00000000 0x00000000 0x00000000 0x00000000
0x602080: 0x00000000 0x00000000 0x00000000 0x00000000
0x602090: 0x00000000 0x00000000 0x00000000 0x00000000
0x6020a0: 0x00000000 0x00000000 0x00020f61 0x00000000
0x6020b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x6020c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x6020d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x6020e0: 0x00000000 0x00000000 0xdeadbeef 0x00000000
0x6020f0: 0x00000000 0x00000000 0x00000000 0x00000000
0x602100: 0x00000000 0x00000000 0x00000000 0x00000000
0x602110: 0x00000000 0x00000000 0x00000000 0x00000000
0x602120: 0x00000000 0x00000000 0x00000000 0x00000000
0x602130: 0x00000000 0x00000000 0x00000000 0x00000000
位移很奇怪,移动了30个字节才开始赋值。。为了是30个字节?
【 在 tonyjansan 的大作中提到: 】
: 改成static_cast是可以的,另外改了以后就不需要:
: static_cast(Byte*>(pMem)+realSize-sizeof(int)
: 这样调整指针位置了~实际上static_cast与reinterpret_cast的主要区别就在于它会根据赋予指针的值得数据结构来调整指针的位置;比如你malloc了8个字节,实际赋予的就是一个int,这时候这个指针如果用reinterpret_cast来处理就是不安全的~开始的4个字节被按字节拷贝了数据,后边就是不安全的空余字节。
: ...................
编译器相关!我这里居然完全不做偏移...伤不起的MinGW啊...
这是我的memory dump:
pa pb *a *b
5318792, 5318864 5311704, 1
5318796, 5318868 5318760, 5318760
5318800, 5318872 0, 0
5318804, 5318876 0, 0
5318808, 5318880 0, 0
5318812, 5318884 0, 0
5318816, 5318888 0, 0
5318820, 5318892 0, 0
5318824, 5318896 0, 0
5318828, 5318900 0, 0
5318832, 5318904 0, 0
5318836, 5318908 0, 0
5318840, 5318912 0, 0
5318844, 5318916 0, 0
5318848, 5318920 1, 0
//
#include <cstdlib>
const int realsize = 60;
const int signature = 0x0001;
int main()
{
int i = 0;
void* a = malloc(realsize);
void* b = malloc(realsize);
*(static_cast<int*>((void*)(static_cast<char*>(a) + realsize - sizeof(int)))) = signature;
*(static_cast<int*>((void*)(static_cast<char*>(b)))) = signature;
// ...
return 0;
}
【 在 chen24828393 的大作中提到: 】
: 再ubuntu下测试了一下
: 使用语句static_cast替换reinterpret_cast:
: *(static_cast<unsigned int*>(static_cast<Byte*>(pMem) + realsize-sizeof(int))) = signature;
: ...................
嗯。。。
也就说完全没必要使用reinterpret_cast?感觉static_cast能替代reinterpret_cast。
reinterpret_cast的平台不可移植性让我很是不想用它。。
【 在 tonyjansan 的大作中提到: 】
: 编译器相关!我这里居然完全不做偏移...伤不起的MinGW啊...
: 这是我的memory dump:
: pa pb *a *b
: ...................
如果你要对连续内存做反复读写的话,推荐还是定义结构体或者类自己来维护。用cast来做一是效率问题,一是安全性问题~
【 在 chen24828393 的大作中提到: 】
: 嗯。。。
: 也就说完全没必要使用reinterpret_cast?感觉static_cast能替代reinterpret_cast。
: reinterpret_cast的平台不可移植性让我很是不想用它。。