2015-12-18 112 views
2

我读过堆栈正在使用来管理函数调用,其中堆用于存储正在分配的对象。我的理解是,非原始类型的对象将被存储在堆中。我在堆栈&堆的情况下使用下列用法困惑:关于堆栈和堆的说明

1)原始数据类型,MACROS(#define),静态对象,const和extern?
2)栈管理函数调用,但我想知道什么信息与功能推到栈?
3)我读的地方功能相关的本地对象存储在堆栈。所以如果在函数内部发生任何对象分配,堆栈或堆被使用?如果有任何基本类型的对象是在函数内部声明的,那些在哪里存储?

Sree。

回答

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

  2. 无论何时你调用一个函数,它的参数都被压入堆栈。

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

简而言之,编译器计算每个函数需要多少内存(它的所有变量使用的总和)。当函数被调用时,只需将大小添加到堆栈,然后在完成时将其减去。

在最原始的层次上,使用堆内存的唯一时间(不包括库)是当您拨打malloc时。

在Objective-C的情况下,几乎每一个对象在每次你打电话allocnew堆动态分配。 Objective-C的设计方式和堆分配是正常的。 C和C++倾向于在堆上使用动态分配。

+0

2可能或可能不正确,它肯定与64位C ABI不正确(除了可变参数函数) –

+0

@GradyPlayer你的意思是编译器可能选择不复制它? –

+0

如果原始类型是在头中声明的呢?在函数调用期间确切地说什么内容被存储在堆栈中?如果一个函数包含多个参数,那么这些参数如何被推入堆栈? –

1

为了理解真正发生了什么,您应该构建一个小型的c程序并生成汇编代码。

,你会发现有以下内容:

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

摘要

  • 原始值和结构被存储下一个返回地址的函数的堆栈
  • 以上几个字节大的存储器分配是在堆空间上作出调用。这包括使用malloc创建的对象和数组。