【问题标题】:c++ - Get size of a single element or element count allocated using operator new[]c++ - 使用运算符 new[] 获取单个元素的大小或分配的元素计数
【发布时间】:2012-12-14 01:05:42
【问题描述】:

有没有办法获取单个元素的大小或使用 operator new[] 分配的元素计数?

我的意思:

void* Object::operator new[](size_t size)
{
    void *temp = ::operator new(size);

    //Get size of single element or count of elements being allocated

    return temp;
}

我为什么需要它:

operator new(size_t)operator new[](size_t) 仅在对象在堆上分配时被调用,所以我有了一个基于此创建 c++ 垃圾收集的想法。

  1. 所有对象都继承自Object
  2. Object 类覆盖 operator new(size_t)operator new[](size_t),如下所示:

    void* Object::operator new(size_t size)
    {
        Object& result = *static_cast<Object*>(::operator new(size));
        result.referenceCount = (int)&result;
        return &result;
    }
    
  3. Object 的构造函数使用此信息:

    Object::Object()
    {
        if ((void*)referenceCount != this)
        {
            referenceCount = -1; //stack object no reference counting
        }
        else
        {
            referenceCount = 1; //heap object count references
        }
    }
    
  4. 垃圾收集器用户referenceCount 使用的字段。

我现在需要的是实现operator new[](size_t) 来设置referenceCount,这就是为什么我需要单个元素的大小或元素计数。为每一个不可能的对象执行operator new[](size_t)

有什么想法吗?

【问题讨论】:

  • 引用计数不是 GC。为此使用共享指针,并有选择地这样做,并非没有充分的理由。即使除此之外,你的想法充其量也是非常老套的。
  • 1) 此代码在 64 位平台上被破坏,int 无法可移植地存储指针值。 2) 在栈上创建的对象会有一个未初始化的referenceCount 成员,所以你不能在构造函数中安全地访问它。
  • @Jonathan Wakely 1) 64 位程序上的 int 和指针有 64 位大小,32 位程序上的 int 和指针有 32 位大小! 2)referenceCount 未初始化,但通过在 operator new 中设置它,我可以假设它将具有适当的值(正如 delan 评论的那样,它很hacky)
  • 1) 不,int 在 64 位平台上是 32 位的,查一下。 2) 不,对于堆栈对象,没有任何东西可以初始化成员,因此它甚至可能与 this 具有相同的值。
  • 1) 我写了一个快速测试,你是对的。这个artucule en.wikipedia.org/wiki/64-bit_computing 愚弄了我(第一句话)。 2)读入我的代码

标签: c++ object memory-management garbage-collection creation


【解决方案1】:

这对我来说似乎很 Java 风格。简单地用 Java 编写程序会更简单吗?如果您使用惯用的 C++ 开始,那么将来必须维护您的 C++ 代码的任何人都会感激它。例如,使用智能指针来管理您的内存,而不是尝试基于从 Object 继承的所有内容来实现垃圾收集。

我应该指出,您在条件列表中遗漏了“禁止多重继承”,因为在存在多重继承的情况下,您将原始的、未初始化的内存转换为 Object* 可能无法进行所需的指针调整访问referenceCount的正确地址。

此外,如果referenceCount 的内存在构造时恰好包含基于堆栈的Object 的地址,您的代码将认为它是堆分配的,并在您删除堆栈指针时最终导致UB。

但毕竟如果你仍然真的真的很想这样做,我认为你唯一的选择是使用 CRTP 自动将数组 new 运算符注入每个子类。至少这样你就不必为每个孩子自己写了。

【讨论】:

  • 每个段落都值得 +1。
猜你喜欢
  • 1970-01-01
  • 2010-12-29
  • 2019-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多