c++ - 使用 placement new 了解 C++ 中的内存访问

标签 c++ pointers memory-management

目前正在学习 C++,我正在重新访问一个小型内存管理器,我们的教授已经部分将其作为练习编写,并且由于我太长时间忽视了我的 C++ 技能,所以我无法理解内存和新布局的实际工作原理.所以基本上我有多个 Bucket 对象,它们都包含一定数量的 block ,每个 block 都可以有一定数量的内存。 BucketAdmin 类具有所有这些 Bucket 对象。

BucketAdmin::BucketAdmin(void)
{
m_baseMemory = reinterpret_cast<unsigned char *>(malloc(sizeof(Bucket) * NUM_OF_BUCKETS) );

Bucket* base_pointer = reinterpret_cast<Bucket*>(m_baseMemory);
std::cout << &base_pointer<< "     "  <<  &base_pointer + sizeof(Bucket) *     NUM_OF_BUCKETS  << "     " << sizeof(Bucket) * NUM_OF_BUCKETS << std::endl;

for (unsigned short i = 0; i < NUM_OF_BUCKETS; i++)
{
    m_buckets[i] = new (&base_pointer[i])Bucket(m_bucketSizes[i], BUCKET_CAPACITY/m_bucketSizes[i]);
}
}

所以这里的这段代码让我很困惑。一个桶的大小为 16 字节(如 sizeof(Bucket) 所述,桶的数量为 5。这意味着 m_baseMemory 分配了 80 字节的 ram 并且是一个字符指针(reinterpret_cast 是如何工作的,为什么它被使用两次?)。接下来,通过将内存地址从之前转换为 Bucket 指针来创建一个 bucket 指针 - 究竟是如何以及为什么?当我输出两个地址时,它们彼此非常不同。我理解前两个的方式lines是分配了80字节的内存,其地址保存在m_baseMemory中。然后,因为我们要构造Bucket对象,所以该指针被转换为Bucket指针,这样我们就可以遍历for中的Bucket-addresses循环(基本上一个 i 是 i*sizeof(Bucket) 的偏移量,所以 i*16,对吗?)没有具体说明每个 Bucket 对象所需的偏移量。

那么,由于在 &base_pointer[i] 位置使用了 placement new,它们不应该相同吗?我不明白这两种内存地址(m_baseMemory、base_pointer)之间的差异如此之大。当我将 base_pointer 地址与 base_pointer 地址加上分配的内存进行比较时,我应该得到一个大 80(十进制)的地址,但是当我比较数字时,它相差数百?一个例子: base_pointer 地址为:010FFA6C base_pointer 地址 + sizeof(Bucket) * NUM_OF_BUCKETS 为:010FFBAC

即使 sizeof(Bucket) * NUM_OF_BUCKETS = 80 会被解释为十六进制,它也会加上 128 (8*16),而不是这里的 320。老实说,我不明白这是如何计算的,所以不胜感激。

谢谢。

最佳答案

造成混淆的主要原因是,当您应该查看其值时,您却查看了 base_pointer 的地址。

您似乎错过的另一件事是,将 k 添加到指针会将 k + sizeof(what the pointer points to) 添加到地址。

&base_pointer 是变量的地址,而不是分配内存的地址,所以 &base_pointer + sizeof(Bucket) * NUM_OF_BUCKETS 是一个地址 80 * sizeof( Bucket*) 个字节。
80 * sizeof(Bucket*) 在 32 位目标上是 320。

您感兴趣的地址是base_pointerm_baseMemory + k * sizeof(Bucket)base_pointer + k 表示相同的地址,&base_pointer[k] 也是如此。

关于c++ - 使用 placement new 了解 C++ 中的内存访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39948194/

相关文章:

c - While 循环使用 realloc,打印时不会更新数组

c++ - 将 64 位整数转换为 7 位字符数组

c++ - 如何在链表的节点之间移动?

c - OS X 上的 malloc 问题

c++ - 两个几乎相同的 C++ 程序,一个运行良好但另一个出现运行时错误

c++ - 使用指针交换数组的内容

c - 由于内存指针的 free() 语句,非零退出状态 139

c++ - C/C++ - HWInfo - libhd - 如何获取所有可用设备的名称列表?

c++ - 展平一系列序列(序列)

c++ - Qt QGraphicsSvgItem 缩放和调整大小