堆叠和放大器的澄清堆

时间:2015-12-18 00:50:53

标签: objective-c heap-memory stack-memory

我已经读过堆栈用于管理函数调用,其中堆用于存储正在分配的对象。据我所知,非原始类型的对象将存储在堆中。在堆栈和放大器的情况下,我对以下用法感到困惑堆:

1)原始数据类型,MACROS(#define),静态对象,const和extern?
2)堆栈管理函数调用,但我想知道与函数相关的哪些信息正在推送到堆栈? 3)我在某处读到函数相关的本地对象存储在Stack中。那么如果对象的任何分配发生在函数内部,那么使用堆栈或堆?如果在函数内声明了任何原始类型对象,那么它们存储在哪里?

SREE。

2 个答案:

答案 0 :(得分:1)

  1. 宏在编译时解析。 Consts,globals等是数据段的一部分 - 而不是堆栈或堆。 https://en.wikipedia.org/wiki/Data_segment

  2. 每当你调用一个函数时,它的参数都会被压入堆栈。

  3. 函数内的所有原语,局部变量等都在堆栈中分配。

  4. 简化来说,编译器会计算每个函数需要多少内存(其所有变量用法的总和)。调用该函数时,只需将大小添加到堆栈中,然后在完成时将其减去。

    在最原始的级别上,使用堆内存的唯一时间(不包括库)就是在您调用malloc时。

    在Objective-C的情况下,每当您调用allocnew时,几乎每个对象都会在堆上动态分配。 Objective-C的设计方式和堆分配是正常的。 C和C ++倾向于在堆上使用动态分配。

答案 1 :(得分:1)

要了解真正发生的事情,您应该构建一个小型c程序并生成它的汇编代码。

你会发现以下内容:

  1. 宏应该在编译时评估,而不是在运行时评估。
  2. 常量,全局变量和静态事物被声明为常量并保存到可执行文件中。
  3. 原始数据变量或指针存储在CPU寄存器中(速度极快但数量有限)或存储在内存中的堆栈帧中(更多空间但速度慢约1000倍)。要了解堆栈帧,您应该查看this explanation。基本上是通过将堆栈指针(指向新值放入堆栈的内存位置)向下移动(堆栈从大内存地址扩展到较小内存地址)来构建堆栈帧,因此堆栈上有一些未使用的空间,在函数中可以在本地使用。
  4. 如果你调用一个函数,返回地址(调用前的指令指针+ 1)被压入堆栈,所以当函数返回时,执行跳转到返回地址,方法是从栈中弹出返回地址并跳转它。
  5. 如果你的函数有很多参数,那么在调用函数之前,参数7,8等等都存储在堆栈中。所有先前的参数都存储在寄存器
  6. 与堆栈不同,堆空间由系统分配,只能通过中断程序并让操作系统为程序分配内存(这将在malloc调用中发生)来访问(据我所知)。在分配对象([NSObject alloc])时,可以在堆内存中找到它们。
  7. <强>摘要

    • 原始值和结构存储在堆栈上函数调用的返回地址旁边
    • 在堆空间中进行大于几个字节的大内存分配。这包括使用malloc创建的对象和数组。