C函数内存分配
在C语言中,函数是在什么时候分配的,它在内存中的什么位置C函数内存分配,c,memory,memory-management,C,Memory,Memory Management,在C语言中,函数是在什么时候分配的,它在内存中的什么位置 首先编译程序时是为函数分配内存,还是在第一次看到函数调用时分配内存?它是在堆栈上还是在代码段中分配的?C函数的内存总是在函数加载到内存时从代码段分配的。如果函数属于动态链接库,程序可能会在任意时间加载和卸载它。你的问题是个好问题,但要为一些额外的复杂性做好准备,因为有些东西会触及运行代码的CPU中的裸晶体管 我选择悲惨地失败,试图把它浓缩成4种类型 全局存储 代码存储 本地存储 动态存储 代码存储应该是非常直接的,所以我将把它复杂化一
首先编译程序时是为函数分配内存,还是在第一次看到函数调用时分配内存?它是在堆栈上还是在代码段中分配的?C函数的内存总是在函数加载到内存时从代码段分配的。如果函数属于动态链接库,程序可能会在任意时间加载和卸载它。你的问题是个好问题,但要为一些额外的复杂性做好准备,因为有些东西会触及运行代码的CPU中的裸晶体管 我选择悲惨地失败,试图把它浓缩成4种类型
- 全局存储
- 代码存储
- 本地存储
- 动态存储
全局数据存储是RAM,所有非函数内声明的变量(每个声明只有一个实例)加上声明为静态的变量(函数内或函数外)。它们由绝对(或准)地址引用 常数可能有也可能没有自己的ROM存储区。。。它的编译器/优化是特定的
函数的本地存储是一个包,用于传递参数/返回和本地变量(在其中声明,因此仅由它可见),对函数的每个调用都需要一个单独的包,以便每个调用都获得其单独的上下文 通常(有令人难忘的例外)我们使用调用堆栈机制来堆积每个函数调用生成的几个本地存储区域。它越来越不确定,但您会发现这是一个堆栈帧,它随着内存地址的递减而增长 因此,本地存储是编译器函数调用代码(自动完成)放置函数的参数、被调用函数的返回占位符、调用函数的返回地址以及所有非静态(并优化为内部寄存器用法)变量的地方。每个电话一个。引用这些局部变量和参数的函数代码将。。通过堆栈指针加上偏移量引用后者,偏移量是指向当前堆栈帧结束地址的CPU寄存器(否则函数代码怎么知道内存地址?) 调用函数需要设置函数的本地存储,最终将参数复制到函数中(推入堆栈),并初始化一些局部变量,然后跳转到函数代码。返回是将被调用函数返回值复制到调用函数本地存储中,销毁被调用的F本地存储,将堆栈指针放在先前堆积的本地存储包的末尾,然后跳转到保存的调用方下一个指令地址(弹出)。都做完了 查看单个C进程的内存快照,您可以看到一个包含多个底部堆叠的本地存储区域的堆栈,这些存储区域将按照特定程序执行的函数调用/返回模式进行增长和收缩
动态内存通常由malloc和free管理:通过指针访问的内存块的不断增长的地址堆栈的管理员。这形成了一个命名错误的堆区域(因为到时候你很可能会得到瑞士奶酪,而不是堆) 这些内存块可以用于任何目的,挑战在于确保人们不会忘记释放它们,否则最终会“泄漏”到调用堆栈中(很容易看出其破坏性有多大) 使用malloc/free管理的动态内存需要一些额外的规则,但对于避免巨大的本地存储或浪费的全局存储(在函数需要处理大量数据并且可能被调用几次的情况下,或者在很少需要内存的大数据块的情况下)非常有用 Dyn内存区域通常夹在全局和堆栈之间。。。某些嵌入式编译器允许您指定两个编译器的大小 Malloc和free并不是管理动态内存的唯一方法,我目前正在使用一个自行开发的反向引用分配器,它不需要free()。无纪律的代码和无泄漏。。。。耶 内联函数 很好的解释 我想提供有关内联函数的内存分配的详细信息,但没有介绍。内联函数可以看作是一个宏,其中对函数的调用被代码替换,并且还进行参数求值。
在函数之前给出一个关键字inline不需要使它成为一个inline函数,它只是建议编译器这是一个inline的候选者。编译器最终选择这是否可以是内联函数。因此,内存分配类似于函数。函数中的变量从堆栈段获取内存,对吗?只有代码(或指令)存储在代码段中。这个想法正确吗?@Jay局部变量是从自动存储器(通常是堆栈)分配的,而静态变量是从静态存储器分配的。还有一些字符串常量和数组聚合可以复制到静态内存中,也可以保留在代码段中,具体取决于体系结构。标准没有规定一种或另一种方式。@dasblinkenlight“静态是从静态存储中分配的”。。。静态存储是什么?堆?@SwanandPurankar:静态存储就是