自动对象驻留在哪里(与演示一起)
where does an automatic object live in( with a demo )
我想在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
所以我可以理解前三行,我需要一些帮助来理解其余的
感谢您的关注!
标准免责声明:的实现可能与完全不同,但大多数在x86或类似平台上,可能会大致如下所述。
当您定义具有自动存储持续时间的对象时,该对象本身将在堆栈上分配。因此,让我们考虑一个稍微简化的向量:
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这样具有批次寄存器的机器上,我们可以期望大多数本地/auto变量都在寄存器中。在x86上,我们有足够少的寄存器,堆栈使用非常普遍(尽管x86-64的可用寄存器翻了一番,这有很大帮助)。
vector本身然后使用 查看您包含的代码的具体细节:在我看来,大多数其余代码都在调用Allocator
对象在其他地方(通常,但不一定是自由存储区)获取存储您关心的数据(即,在vector 中存储的元素)的存储空间。std::string
对象的构造函数和析构函数。不幸的是,您使用了可怕的AT&T语法,这使得它几乎无法阅读。
自动变量通常在堆栈上分配,但它们的实现当然可能使用其他内存。在标准容器的情况下,它们将使用动态内存分配或Allocator
用户提供的任何内存。所以,在这个例子中,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
//store address of `s` (which is 12 bytes below %ebp) in eax
9: 89 04 24 mov %eax,(%esp) //put it on a stack (argument)
c: e8 00 00 00 00 call 11 <__Z7autovarv+0x11> //call constructor
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> //call destructor
1c: c9 leave //restore esp and ebp
1d: c3 ret //return
1e: 90 nop
1f: 90 nop
- C++我需要了解在哪里使用指针和双指针
- 未定义的引用在哪里
- 谷歌测试中的期望值存储在哪里
- 尽管遵循了规则,内存泄漏在哪里
- 静态数据成员模板专用化的实例化点在哪里
- 在哪里放置我的函数?进入我的母语 Gui 还是进入我的演示者?
- 在哪里声明结构运算符重载
- C++ 中的自定义异常:在哪里定义它们?
- 常量参数存储在哪里 (C++)?
- 如何在 c++ 中确定一条指令(以字节为单位)在哪里结束,另一条指令从哪里开始?
- 此递归函数的每次迭代的值存储在哪里?
- 如何告诉本机节点模块所需的dll存储在哪里?
- 在哪里存储跨平台C++应用存储?
- C++泛型类错误,问题出在哪里?
- 在标准中,模板参数的语法在哪里定义,例如,'std::function<int(char)>'?
- 将类作为主要参数的语法在哪里需要?
- 模板参数在 C++ 中存储在哪里?
- 我的重复检查代码中的错误究竟在哪里?
- 自动对象驻留在哪里(与演示一起)
- 在哪里放置要与Windows用户的桌面设置一起漫游的用户数据文件?