【问题标题】:Distinguish if C++ object was dynamically allocated or not? [duplicate]区分 C++ 对象是否是动态分配的? [复制]
【发布时间】:2013-04-01 16:03:44
【问题描述】:

C++ 对象的内存可以在编译时分配(在堆栈上)。

MyClass mc;

或动态(常用方法)

MyClass *mc = new MyClass();

是否有任何方法内置于 C++ 语言中,可以区分对象是以静态方式还是动态方式分配的?内置我的意思是使用模板或关键字等(非编程/算法方法)。

本质上,目标是“标记”未使用new 运算符分配的对象(动态分配)。

【问题讨论】:

  • 在编译时不会分配任何东西,除非你算上一些 constexpr 的东西。
  • 重要提示:未分配; 类的实例(又名对象)是。
  • 您是在问如何识别是否在堆上分配了某些东西?您可以通过 operator new 的重载来实现
  • @StoryTeller: 不是真的,如果它是一个更大对象的一部分,或者如果它不是直接用 new 分配的(比如调用到::operator new,然后是新位置——听起来很尴尬?想想std::make_shared)

标签: c++ memory-management


【解决方案1】:

不,无法检测对象是静态分配的还是动态分配的。至少在大多数人使用这些词的意义上:堆栈与堆。 C++ 标准考虑了三种类型的存储,静态存储(全局变量、类的静态成员、静态局部变量)、动态分配和自动存储。

第三个使事情复杂化,因为具有 auto 存储的对象可能被分配为可能在三个领域中的任何一个中分配的更大对象的一部分。例如,考虑一个在堆中分配并由shared_ptr 管理的对象,它可能是直接用new 分配的,或者它可能是通过make_shared 创建的。在第一种情况下,使用您的类型调用new,但在后一种情况下,动态分配更大的块并就地构造对象:

std::shared_ptr<T> p = std::make_shared<T>();
std::shared_ptr<T> q( new T() );

现在有趣的一点是为什么你关心对象是如何创建的,因为可能有不同的事情可以解决你真正的问题不涉及您的要求。

【讨论】:

    【解决方案2】:

    正如 StoryTeller 所说,您可能想要的是重载 new 运算符。

    class A{
        private:
            bool isDynamic;
    
        public:
            void *operator new(size_t size){
                isDynamic = true;
            }
    

    【讨论】:

    • 差不多。我认为 OP 想要捕获 all 堆分配。这意味着必须覆盖全局 operator new。此外,您的示例存在缺陷,因为 operator new 仅返回指向原始内存的指针。
    • 也许,但我解释他的问题的方式是他在谈论一个特定的课程。他可能需要再澄清一点。
    • 我又添加了一行来澄清。重载new 运算符实际上是一个好方法,因为未使用new 分配的类将具有false 的布尔值。
    • @ParkerKemp 如果我重载了基类的new 运算符,如果本质上调用了派生类的new 运算符,这个方法还能工作吗?基类如何知道该类是否使用new 分配?
    • 这只是语义顺便说一句,但你应该了解“类”和“对象”之间的区别。我相信您了解这些概念,但在与他人交流时区分两者很重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 2020-06-23
    相关资源
    最近更新 更多