如何判断一个C++对象是不是在堆栈上

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何判断一个C++对象是不是在堆栈上相关的知识,希望对你有一定的参考价值。

堆空间一般有操作系统的堆管理器来处理,栈空间一般是应用程序自动回收管理的,以Window 参考技术A 为什么要这种判断?似乎没有办法判断

对象向量是不是在 C++ 中的堆或堆栈上分配?

【中文标题】对象向量是不是在 C++ 中的堆或堆栈上分配?【英文标题】:Does an object vector allocate on the heap or stack in C++?对象向量是否在 C++ 中的堆或堆栈上分配? 【发布时间】:2020-03-30 02:53:14 【问题描述】:

我已经看到很多关于这个主题的类似问题,但我没有看到这个问题的明确答案。考虑以下代码:

typedef struct Student

    int id;
 Student;

vector<Student> students();
for( int i = 0; i < 10; i++ )

    Student s();
    s.id = i
    students.push_back( s );

这个向量如何分配内存?据我了解,每个Student s 都应该在堆栈上拥有它的内存,并在循环迭代时被取消分配,所以如果我稍后尝试访问这些数据,这应该会产生未定义的行为。但是如果我用vector&lt;int&gt; 做同样的事情,它不会产生未定义的行为。

这是正确的吗?无论哪种方式,我的目标是创建一个vector&lt;Student&gt;,其中对象在堆上分配,而不必使用vector&lt;Student*&gt;。这可能吗?

【问题讨论】:

对象被复制/移动到向量中。向量处理其内存的方式,这些副本很可能在堆上。 请注意vector&lt;Student&gt; students(); 声明了一个名为students函数,它不接受任何参数并按值返回vector&lt;Student&gt;。删除括号以定义矢量对象。 students 在堆栈上。它管理的内存在堆上(Student 元素)。 @JedediahHeal “堆栈”和“堆”在物理上没有分离,它们只是同一内存的不同区域。对象被复制,而不是移动或引用。 (C++ 不是 Java。)将对象从内存的一部分复制到另一部分总是相同的。 从技术上讲,C++ 中根本没有“堆”和“栈”。 std::vector 采用动态内存分配来管理对象集合,其中对象的数量在运行时确定。堆和堆栈描述了一些(不是全部)实现如何管理内存的细节 - 在此类系统上,动态内存分配通常使用堆内存。 【参考方案1】:

根据vector in cppreference,一个vector需要两个模板参数,T(vector中元素的类型)和Allocator,默认设置为std::allocator&lt;T&gt;std::allocator's allocate function,必须调用按向量分配内存:

通过调用 ::operator new(std::size_t) 或 ::operator new(std::size_t, std::align_val_t) 分配 n * sizeof(T) 字节的未初始化存储(C++17 起),但未指定何时以及如何调用此函数。指针提示可用于提供引用的局部性:分配器,如果实现支持,将尝试分配新的内存块尽可能接近提示。

因此,只要没有给定分配器到向量,所有新成员都存储在堆中。尽管大多数分配器必须使用堆来分配内存。

【讨论】:

【参考方案2】:

创建std::unique_ptr&lt;Student&gt; ... 还可以使用std::vector&lt;std::unique_ptr&lt;Student&gt;&gt; 类型来保存数据。 这样您就不必担心通过 unique_ptr 删除堆存储上分配的内存。

【讨论】:

以上是关于如何判断一个C++对象是不是在堆栈上的主要内容,如果未能解决你的问题,请参考以下文章

对象向量是不是在 C++ 中的堆或堆栈上分配?

C++:如何在堆栈上创建对象数组?

C++如何判断两个对象是不是是同一个对象?判断两个对象的地址可以吗?

在 C++ 中,在对象内分配多个数据时,堆栈分配是不是更有效? A_Heap 类在下面的程序中效率会降低吗? [复制]

如何在 C++ 中“返回一个对象”?

在堆栈 C++ 上创建的对象中的无效数据