C++向指针地址添加 4 个字节

C++ adding 4 bytes to pointer address

本文关键字:字节 添加 地址 指针 C++      更新时间:2023-10-16

我有一个关于指针和内存地址的问题:

假设我有以下代码:

int * array = (int *) malloc(sizeof(int) * 4);

现在在存储内存地址的数组 im 中,我知道 c++ 在向此指针添加 +1 时已经很小心,它将增加 4 个字节,但是如果我想手动添加 4 个字节怎么办?

array + 0x004

如果我正确,这将导致添加 4*4 (16( 字节,但我的想法是手动添加这 4 个字节。

为什么?只是在玩,我试过这个,我得到了一个与我预期的完全不同的结果,然后我研究了,我看到当你向指针添加 +1 时,c++ 已经很小心了(在这种情况下它总和 4 个字节(。

知道吗?

对于指向值为 v 的类型T p的指针,表达式 p+n 将(无论如何在大多数系统上(产生指向地址v+n*sizeof(T)的指针。若要获取指针的固定字节偏移量,可以先将其强制转换为字符指针,如下所示:

reinterpret_cast<T*>(reinterpret_cast<char*>(p) + n)

在 c++ 中,sizeof(char)定义为等于 1。

请注意,访问未正确对齐的值可能会对性能造成很大影响。

需要注意的另一件事是,通常不允许将指针强制转换为不同类型的指针(称为严格锯齿规则(,但显式例外情况是将任何指针类型强制转换为char*并返回。

诀窍是将array的类型转换为大小为 1 字节的任何指针类型,或将指针值存储在整数中。

#include <stdint.h>
int* increment_1(int* ptr) {
    //C-Style
    return (int*)(((char*)ptr) + 4);
}
int* increment_2(int* ptr) {
    //C++-Style
    char* result = reinterpret_cast<char*>(ptr);
    result += 4;
    return reinterpret_cast<int*>(result);
}
int* increment_3(int* ptr) {
    //Store in integer
    intptr_t result = reinterpret_cast<intptr_t>(ptr);
    result += 4;
    return reinterpret_cast<int*>(result);
}

考虑一下,如果你将任意数量的字节添加到类型T对象的地址,使用T类型的指针不再有意义,因为在递增的内存地址处可能没有T类型的对象。

如果要访问对象的特定字节,可以使用指向charunsigned charstd::byte的指针来实现。此类对象的大小为字节,因此递增的行为就像您想要的那样。此外,虽然C++规则不允许使用不兼容的指针访问对象,但这三种类型是该规则的例外,并允许访问任何类型的对象。

所以,鉴于

int * array = ....

您可以像这样访问索引 4 处的字节:

auto ptr = reinterpret_cast<unsigned char*>(array);
auto byte_at_index_4 = ptr + 4;
<小时 />
array + 0x004

如果 im 正确,这将导致添加 4*4 (16( 字节

假设sizeof(int)恰好是 4,那么是的。但是 int 的大小不能保证为 4。