【发布时间】:2016-10-09 20:25:18
【问题描述】:
目前正在学习 C++,我正在重新审视我们的教授部分编写的一个小型内存管理器作为练习,由于我太长时间忽视了我的 C++ 技能,我无法理解内存和放置 new 的实际工作原理.所以基本上我有多个 Bucket 对象,它们都包含一定数量的块,每个块都可以有一定数量的内存。 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]);
}
}
所以这里的代码让我很困惑。 Bucket 的大小为 16 字节(如 sizeof(Bucket) 所述,桶数为 5。这意味着 m_baseMemory 分配 80 字节的 ram 并且是 char 指针(reinterpret_cast 如何准确工作以及为什么使用两次?). 接下来,通过将之前的内存地址转换为 Bucket 指针来创建存储桶指针 - 这是如何以及为什么会这样?当我输出两个地址时,它们彼此非常不同。我理解前两个的方式行是分配了80字节的内存,其地址保存在m_baseMemory中。然后,因为我们要构造Bucket对象,所以将该指针强制转换为Bucket指针,这样我们就可以遍历for中的Bucket-adresses-循环(基本上一个 i 是 i*sizeof(Bucket) 的偏移量,所以 i*16,对吗?)没有具体说明每个 Bucket 对象所需的偏移量。
那么,在位置 &base_pointer[i] 使用放置 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。老实说,我不明白这是如何计算的,因此不胜感激。
谢谢。
【问题讨论】:
-
对齐要求可能吗?
Bucket需要对齐,而char不需要。 -
16 字节?你确定它不是 16 位(2 字节),因为这样会更有意义吗?
-
@TomaszPlaskota sizeof 返回 16,所以我猜这意味着 16 个字节,不是吗?
-
听起来你不明白指向不同类型的指针的区别
标签: c++ pointers memory-management