C+中的内存组织+; 我一直在阅读C++中如何分配内存。

C+中的内存组织+; 我一直在阅读C++中如何分配内存。,c++,compiler-construction,C++,Compiler Construction,需要提及的几个资源: 根据我的阅读,我想澄清几点: 根据第4节Stack“Stack,其中存储自动变量,以及每次调用函数时保存的信息” 假设: class myClass{ int a; char b; public: myClass(int a,char b) { this->a = a; this->b = b; } }; 1) 根据我所读到的,当我们编译这段代码时,二进制文件位于程序内存中,堆栈上还没有分配任何内容。对吗

需要提及的几个资源:

根据我的阅读,我想澄清几点:

根据第4节Stack“Stack,其中存储自动变量,以及每次调用函数时保存的信息”

假设:

class myClass{
  int a;
  char b;
  public:
  myClass(int a,char b)
  {
   this->a = a;
   this->b = b;
  } 
};
1) 根据我所读到的,当我们编译这段代码时,二进制文件位于程序内存中,堆栈上还没有分配任何内容。对吗

现在我的主要观点是:

int main()
{
 myClass Ob(1,'c');
 return 0;
} 
2) 现在在堆栈上创建一个大小为5字节(4字节(int),1字节(char)-32位OS的对象Ob,因为它是一个自动变量。对吗

3) 当调用构造函数
myClass(int a,char b)
时,是否在堆栈上为构造函数创建临时变量(参数a,b),然后在创建对象Ob后销毁?就像我们通过按值传递参数来调用函数一样

现在假设另一节课

class pointerClass {
 int a;
 char* b;
 public:
 pointerClass(int size){
 b= new char[size];
 a=size;
 }
}; 
现在主要是:

int main()
{
 pointerClass ptr(10) ; //Step 1
}
4) 这是否意味着在堆栈上创建了大小为8字节(inta(4字节)、char*b(4字节,即,它只是保存一个指向堆的地址)的ptr对象?此外,由char*b的内容指向的10字节内存(对应于堆上分配的新char[10])是否正确

5) 当我们通过引用将参数传递给函数时,例如
fn(int*a,char*b)
fn(int&a,char&b)
这是否意味着在堆栈上为函数创建一个临时指针/引用,该指针/引用指向函数返回时传递和销毁的实际对象?或者更确切地说是传递实际对象,而不是在堆栈上为函数创建和销毁临时指针/引用

我昨天问了这个问题,但我对答案不满意:

6) 当我们重载一个fn时,比如
fn(int-a,char-b)
fn(int-a,char-b)
我们可以从main调用
fn(a,b)
下铸
static_cast(fn)(a,c)//调用fn(整数a,字符b)
static_cast(fn)(a,c)//呼叫fn(int&a.char&b)
这里到底发生了什么?什么是空(*)

谢谢

  • 正确的
  • 正确(虽然可能不是五个字节,可能是八个字节)
  • 正确的
  • 正确的
  • 临时指针/引用是在堆栈上创建的,不知道为什么您对前面给出的答案不满意。我认为它是正确的
  • void(*)(int,char)
    是一种类型,特别是一个指向void函数的指针,该函数包含两个参数和一个int和一个char。显然,这个强制转换迫使编译器选择您想要的函数的版本,尽管对我来说这是可能的
  • 当然,必须添加强制性警告,上面没有任何关于C++的要求,这只是C++是如何实现的。
  • 正确-分配发生在运行时
  • 部分正确-该标准不使用术语堆栈和堆,它只要求对象的行为。但是,堆栈是实现此功能最常用的方法。此外,编译器允许用填充字节填充结构,因此不应推测对象的大小。这被称为。只需使用
    sizeof
    即可获得大小
  • 部分正确-通过值传递和返回确实需要一个副本构造函数来访问调用,但在某些情况下这些调用可能会被忽略。该过程称为

  • 部分正确-指针仅指向具有动态存储的对象。但指针的大小可能会有所不同
  • 指针或引用是在函数的本地创建的,但它指向或引用了传递其地址的对象。这里不需要复制,也不会发生任何情况
  • 每个变量都有C和C++的数据类型。类型转换允许您灵活地强制编译器将指向一种数据类型的指针视为指向完全不同的数据类型的指针。由于函数有一个类型,指向函数的指针也有一个类型,类型转换允许您强制编译器将函数指针从一种函数类型处理为完全另一种类型,从而本质上允许您调用所需的重载函数版本
    首先,我应该指出,您展示的图表非常简单 依赖于系统。例如,在Solaris下,操作系统 系统内存根本没有映射到用户地址空间。 而最频繁的映射只有三个映射段 用户内存,至少在程序开始时:一个代码 底部分段(但不是绝对底部,因为 地址0通常不会被映射),它上面的数据段, 顶部有一个堆栈段(向下生长),带有一个大的 堆栈和数据之间的未映射内存孔

    一旦动态启动,所有这些都会完全改变 装载

  • 不,在你完成一个代码之后(在更大的意义上 编译),可执行文件位于文件中,而不是内存中。这个 程序在执行之前不会加载到内存中。 (早期Unix和嵌入式系统中曾经有一些例外情况 系统,即使是今天。但对于像 Windows和现代Unix,这是事实。)

  • 变量将在堆栈上创建。但它几乎会 由于对齐,肯定大于5字节 考虑因素。(对于大多数32个字节,8个字节是最小的 在C++中,对象创建是两个步骤: 内存分配和调用构造函数。大多数 实现所需的所有内存 将分配函数中使用的所有对象 立即,在函数的顶部;在某些情况下,额外 内存也将分配到每个变量的任一侧, 由于调试原因,内存将是初始的