[英]Pointer arithmetic confusion or weird behavior
当以下运行时,我得到 _pfloatPos 和 _charPos 不同:
float* const _pData = new float[0x50000000];
float* const _floatPos = _pData + 0x400000B0;
char* const _charPos = ((char*)_pData) + 0x400000B0 * 4;
if ((char*)_floatPos != _charPos)
{
throw "Derp.";
}
也许我脑子有雾,错过了一些基本的东西。 这两个地址应该是一样的吧?
我看着拆机。 1000002C0h 是 4 * 0x400000B0 。 对于第二个,它似乎在某些时候被截断了。
float* const _floatPos = _pData + 0x400000B0;
00007FF7CE48F6E2 mov rax,1000002C0h
00007FF7CE48F6EC mov rcx,qword ptr [_pData]
00007FF7CE48F6F0 add rcx,rax
00007FF7CE48F6F3 mov rax,rcx
00007FF7CE48F6F6 mov qword ptr [_floatPos],rax
char* const _charPos = ((char*)_pData) + 0x400000B0 * 4;
00007FF7CE48F6FA mov rax,qword ptr [_pData]
00007FF7CE48F6FE add rax,2C0h
00007FF7CE48F704 mov qword ptr [_charPos],rax
我使用的是 Visual Studio 2017 版本 15.9.2,但我不确定编译器的版本。
您需要0x400000B0 * 4L
否则乘法将溢出。
两个整数文字 0x400000B0 和 4 每个都只给出 4 个字节(即使在 x86-64 中也是如此),因此将它们相乘会导致溢出。 附加 L's 不会改变任何东西。 附加 LL 使它们成为 64 位,并解决了问题。 但我的解决方案是从现在开始将 std::int64_t 用于整数。
测试:
#include <iostream>
#include <cassert>
using namespace std;
int main()
{
{ // plain literals
float* const _pData = 0;
float* const _floatPos = _pData + 0x400000B0;
char* const _charPos = ((char*)_pData) + 0x400000B0 * 4;
assert((char*)_floatPos != _charPos);
}
{ // append L
float* const _pData = 0;
float* const _floatPos = _pData + 0x400000B0L;
char* const _charPos = ((char*)_pData) + 0x400000B0L * 4L;
assert((char*)_floatPos != _charPos);
}
{ // append LL
float* const _pData = 0;
float* const _floatPos = _pData + 0x400000B0L;
char* const _charPos = ((char*)_pData) + 0x400000B0LL * 4LL;
assert((char*)_floatPos == _charPos); // success
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.