Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
自动对象位于何处(带有演示) 我想对C++的内存管理和G++、VC++等实现做一些研究。p>_C++_Assembly - Fatal编程技术网

自动对象位于何处(带有演示) 我想对C++的内存管理和G++、VC++等实现做一些研究。p>

自动对象位于何处(带有演示) 我想对C++的内存管理和G++、VC++等实现做一些研究。p>,c++,assembly,C++,Assembly,第一个问题是自动objectlocal对象位于何处?内置类型、用户定义类型、STL 我认为内置类型存储在堆栈中,这是在编译步骤中完成的。对于一个用户定义的类型?我看到STL数据类型总是在堆内存中。所以我写了一个小函数,用g++编译,用objdump反汇编,看看编译器到底做了什么 #include <string> void autovar(){ std::string s; } 分解结果如下: 00000000 <__Z7autovarv>: 0:

第一个问题是自动objectlocal对象位于何处?内置类型、用户定义类型、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行,我需要一些帮助来理解其余的


谢谢你的关注

自动变量通常在堆栈上分配,但它们的实现当然可能会使用其他内存。对于标准容器,它们将使用动态内存分配或用户提供的任何分配器。因此,在本例中,对象位于堆栈上,但如果它不是空的,则其数据可能位于其他位置

您的程序集评论:

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

自动变量通常在堆栈上分配,但它们的实现当然可能会使用其他内存。对于标准容器,它们将使用动态内存分配或用户提供的任何分配器。因此,在本例中,对象位于堆栈上,但如果它不是空的,则其数据可能位于其他位置

您的程序集评论:

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

标准免责声明:一个实现的工作方式可能完全不同,但大多数都是在x86或类似的平台上,其工作方式可能大致如下所述

定义具有自动存储持续时间的对象时,将在堆栈上分配该对象本身。那么,让我们考虑向量的一个稍微简化的版本:

template <class T, class Allocator = std::allocator<T> >
class vector {
    T *data;
    size_t currently_used;
    size_t allocated;
public:
    // ...
};
因此,当我们分配一个向量时,该对象本身就是数据指针的存储,当前使用和分配的计数器在堆栈上被分配

假设一个典型的32位机器,其中指针和大小各为32位,这意味着堆栈上有12字节的空间。对于更简单的类型,例如int或long,甚至可以想象对于vector之类的类型,我们希望在相当多的情况下看到在寄存器中分配的局部变量。编译器根据可能使用最多的猜测来选择在寄存器中分配哪个。在像SPARC或安腾这样拥有大量寄存器的机器上,我们可以预期大多数本地/自动变量都在寄存器中。在x86上,我们有足够少的寄存器,因此堆栈使用非常普遍,尽管x86-64将可用寄存器增加了一倍,这相当有帮助

然后,向量本身通常使用分配器对象在别处获取存储,但不一定使用空闲存储来存储您关心的数据,即存储在向量中的元素


查看您包含的代码的具体细节:在我看来,代码的其余大部分都在调用std::string对象的构造函数和析构函数。不幸的是,您使用了糟糕的AT&T语法,这使它几乎无法阅读。

标准免责声明:一个实现可以完全不同地工作,但大多数在x86或类似的平台上,可能会大致按照下面所述的方式工作

定义具有自动存储持续时间的对象时,将在堆栈上分配该对象本身。那么,让我们考虑向量的一个稍微简化的版本:

template <class T, class Allocator = std::allocator<T> >
class vector {
    T *data;
    size_t currently_used;
    size_t allocated;
public:
    // ...
};
因此,当我们分配一个向量时,该对象本身就是数据指针的存储,当前使用和分配的计数器在堆栈上被分配

假设一个典型的32位机器,其中指针和大小各为32位,这意味着堆栈上有12字节的空间。对于更简单的类型,例如int或long,甚至可以想象对于vector之类的类型,我们希望在相当多的情况下看到在寄存器中分配的局部变量。编译器根据可能使用最多的猜测来选择在寄存器中分配哪个。在像SPARC或安腾这样拥有大量寄存器的机器上,我们可以预期大多数本地/自动变量都在寄存器中。在x86上,我们有足够少的寄存器,因此堆栈使用非常普遍,尽管x86-64将可用寄存器增加了一倍,这相当有帮助

然后,向量本身通常使用分配器对象在别处获取存储,但不一定使用空闲存储来存储您关心的数据,即存储在向量中的元素


查看您包含的代码的具体细节:在我看来,代码的其余大部分都在调用std::string对象的构造函数和析构函数。不幸的是,您使用了糟糕的AT&T语法,这使它几乎无法读取。

Lea是加载有效地址,但它可能仅用于计算。好的,当您编写函数并生成局部变量时,它会进入堆栈,因此您的变量s将存在于堆栈上,并且
退出此堆栈帧时将不再存在。Lea是加载有效地址,但它可能仅用于计算。好的,当您编写函数并生成局部变量时,它将进入堆栈,因此您的变量s将存在于堆栈上,并且在退出此堆栈帧时将不再存在。也就是说,s仍在堆栈中,它的地址比%ebp低12字节?但是为什么是12个字节,如果我动态地更改s呢。@zoujyjs,我添加了一些文本。Jerry Coffin解释了12个字节-指针、长度和分配长度-在32位机器上,它们通常都是4个字节长。也就是说,s仍然在堆栈中,它的地址比%ebp低12个字节?但是为什么是12个字节,如果我动态地更改s呢。@zoujyjs,我添加了一些文本。Jerry Coffin解释了12字节——指针、长度和分配长度——在32位机器上,它们通常都是4字节长。这很有启发性。所以字符串是一个特殊的向量,是类似的。通常所有不使用new定义的自动对象都在堆栈中,对吗?顺便说一句:免费存储和堆有什么区别?@zoujyjs:任何属于自动存储类的东西,即不使用new而不是global,通常都会在堆栈或寄存器中。通常的术语是,免费存储是由new/delete管理的,而堆是由malloc/free和realloc、calloc等管理的。尽管功能基本相同。谢谢你的回答!这很有启发性。所以字符串是一个特殊的向量,是类似的。通常所有不使用new定义的自动对象都在堆栈中,对吗?顺便说一句:免费存储和堆有什么区别?@zoujyjs:任何属于自动存储类的东西,即不使用new而不是global,通常都会在堆栈或寄存器中。通常的术语是,free存储是由new/delete管理的,而heap是由malloc/free和realloc、calloc等管理的。不过功能基本相同。谢谢你的回答