我想对c++ 的内存管理及其实现(如g++、vc++)做一些研究。
第一个问题是自动对象(本地对象)住在哪里?(内置类型,用户自定义类型,STL...)
我认为内置类型存储在堆栈中,这是在编译步骤中完成的。对于用户定义的类型,事实是什么?我之前在某处看到 STL 数据类型总是在堆内存中。所以我写了一个小函数,用 g++ 编译,用 objdump 反汇编,看看编译器到底做了什么。
#include <string>
void autovar(){
std::string s;
}
反汇编结果如下:
00000000 <__Z7autovarv>:
0: 55 push %ebp //push the old frame pointer
1: 89 e5 mov %esp,%ebp //ebp point to the old
3: 83 ec 28 sub $0x28,%esp//allocate stack space
6: 8d 45 f4 lea -0xc(%ebp),%eax//param or something??
9: 89 04 24 mov %eax,(%esp)
c: e8 00 00 00 00 call 11 <__Z7autovarv+0x11>
11: 8d 45 f4 lea -0xc(%ebp),%eax
14: 89 04 24 mov %eax,(%esp)
17: e8 00 00 00 00 call 1c <__Z7autovarv+0x1c>
1c: c9 leave
1d: c3 ret
1e: 90 nop
1f: 90 nop
所以我能理解前 3 行,我需要一些帮助才能理解其余的
感谢您的关注!
最佳答案
标准免责声明:一个实现可以完全不同地工作,但大多数在 x86 或类似平台上,可能大致如下所述。
当您定义一个具有自动存储持续时间的对象时,该对象自身 将被分配到堆栈上。因此,让我们考虑一个稍微简化的 vector 版本:
template <class T, class Allocator = std::allocator<T> >
class vector {
T *data;
size_t currently_used;
size_t allocated;
public:
// ...
};
因此,当我们分配一个 vector
时,该对象本身(data
指针的存储,currently_used
和 allocated
计数器)在堆栈上分配。
假设一个典型的 32 位机器,其中指针和 size_ts 各为 32 位,这意味着堆栈上有 12 个字节的空间。对于更简单的类型(例如,int
或 long
)和可以想象,甚至对于像 vector
这样的类型,我们期望在很多情况下看到本地人在寄存器中分配。编译器根据(猜测)哪些可能最常使用来选择在寄存器中分配哪些。在像 SPARC 或 Itanium 这样具有很多 寄存器的机器上,我们可以预期大多数 本地/自动变量都在寄存器中。在 x86 上,我们有足够少的寄存器,堆栈使用非常普遍(尽管 x86-64 使可用寄存器加倍,这有很大帮助)。
vector 本身然后使用 Allocator
对象在别处获取存储空间(通常,但不一定是免费存储空间)来存储您关心的数据(即您存储的元素 vector )。
查看您包含的代码的具体细节:在我看来,其余大部分代码都在为您的 std::string
对象调用构造函数和析构函数。不幸的是,您使用了可怕的 AT&T 语法,这使得它几乎不可读。
关于c++ - 自动对象住在哪里(附演示),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16542749/