使用reinterpret_cast转换QGraphicsItem*为long致运行崩溃,用法是否正确?
问题分析与解决方案
你的reinterpret_cast用法存在隐患,崩溃的根源是**long类型的宽度不一定与指针类型匹配**,导致指针地址被截断,在Run Mode中还原时得到无效指针,最终触发崩溃。
具体原因
不同平台和编译器下,long的宽度差异很大:
- 在32位系统中,
long和指针都是4字节,转换不会有问题; - 但在64位Windows系统中,
long仍为4字节,而指针是8字节。此时将8字节的QGraphicsItem*转成long会直接截断高4位的地址信息,转回指针时就会得到一个错误的内存地址,访问自然会崩溃。
Capture Mode和无模式下可能恰好处于32位环境,或者目标指针的地址刚好落在long能存储的范围内,所以没暴露问题;而Run Mode的运行环境(比如64位)触发了地址截断的问题。
正确的实现方式
改用C++标准库定义的**intptr_t或uintptr_t**(需包含<cstdint>头文件),这两个类型的宽度与当前平台的指针宽度完全一致,专门用于安全地将指针转换为整数值存储。
修改后的示例代码:
#include <cstdint> SelectObject() { QGraphicsItem* currentSelectedItem = _scene->itemAt( some location ); intptr_t currentItem = reinterpret_cast<intptr_t>(currentSelectedItem); SelectObjectCapture(currentItem); } SelectObjectCapture(intptr_t currentSelectedItem) { CAPTURE FUNCTION(SelectObjectCapture,currentSelectedItem); QGraphicsItem* currentItem = reinterpret_cast<QGraphicsItem*>(currentSelectedItem); // then using currentItem in code }
注意事项
intptr_t是有符号整数类型,uintptr_t是无符号类型,两者都可以安全存储指针,根据实际需求选择即可;- 必须确保编译时包含
<cstdint>头文件,否则无法使用这两个类型。
内容的提问来源于stack exchange,提问作者tushar
相关产品推荐
相关产品推荐

