在C语言中,什么时候分配和取消分配静态和动态内存?
我现在正在学习C,并试图弄清楚C的内存管理是如何工作的。如果我错了,请纠正我,但我知道: 静态内存分配-这发生在编译时。编译器分配静态内存所需的必要内存 静态内存释放-当块/函数完成运行(对于局部变量)或整个程序完成执行(对于全局变量)时,内存将自动释放 动态内存分配-内存是在运行时分配的,因为此时输入的大小未知 Dynamics memory deallocation—执行free()时内存被释放在C语言中,什么时候分配和取消分配静态和动态内存?,c,memory,memory-management,C,Memory,Memory Management,我现在正在学习C,并试图弄清楚C的内存管理是如何工作的。如果我错了,请纠正我,但我知道: 静态内存分配-这发生在编译时。编译器分配静态内存所需的必要内存 静态内存释放-当块/函数完成运行(对于局部变量)或整个程序完成执行(对于全局变量)时,内存将自动释放 动态内存分配-内存是在运行时分配的,因为此时输入的大小未知 Dynamics memory deallocation—执行free()时内存被释放 这是对的吗?我遗漏了什么吗?C语言中有3种不同的存储持续时间: 静态:变量的生存期就是程序的生
这是对的吗?我遗漏了什么吗?C语言中有3种不同的存储持续时间:
- 静态:变量的生存期就是程序的生存期。它在加载时分配(仅在编译时定义),并且仅在操作系统卸载程序时释放。静态变量是在任何函数之外声明的变量,以及具有
修饰符的局部变量(在函数或块中声明)静态
- 自动:自动变量在块(或函数)内声明,不带存储修饰符。他们的一生从集团开始到集团结束。它们通常在bloc开始时分配,在其结束时解除分配,但由于“仿佛”规则,优化编译器可以更快地分配它们,稍后释放它们,例如,如果bloc位于一个循环中
- 动态:它们是通过
手动分配的,只有malloc
free
\u Thread\u local
存储类修饰符声明的。它们的生存期是线程的持续时间,每个线程都有自己的副本
对于常见的实现,它们的管理方式与静态变量相同:它们在创建线程时由操作系统分配,在线程结束时由操作系统回收(仍然由操作系统回收)
关于你的措辞的一些评论: 静态内存分配-这发生在编译时 注意,编译时和加载时是不同的。在构建时,仅创建一个文件,并且仅在运行时由系统分配内存 静态内存释放-当块/函数完成运行时(对于局部变量),内存将自动释放 范围(本地与全局)和存储持续时间之间存在混淆。函数可以包含静态变量,这是使用
static
关键字的原因之一
动态内存分配-在运行时分配内存,因为此时输入的大小未知
这是程序员使用动态内存的一个可能原因,但可能还有其他原因,例如,因为这样代码会更干净。特别是,当你想用C语言模拟面向对象编程时,动态内存是一个很好的工具。我认为你说的大多数话都是正确的。我只想补充几点
对于全局变量和静态变量,如果初始化它们,它们的值存在于结果二进制中,所以,在编译时发生静态内存分配(实际上它不是内存,但无论如何),但考虑未初始化的全局变量(BSS节)。在生成的二进制图像中只写入它们的长度,因为向编译后的图像中写入数千个零是愚蠢的。在这种情况下,内存分配由加载程序在加载时处理。它分配所需的空间,将它们映射到变量的虚拟地址,并清空内存
free并不一定意味着将未使用的内存分配给操作系统。通常,c标准库会跟踪空闲的块,如果可以的话,会将它们连接起来,以便下次您想要malloc时不会执行sbrk或等效的系统调用,因为它们的成本相对较高。我认为它高度依赖于库的实现请看这里:
VLA
s是动态的还是静态的?@TruthSeeker标准没有定义它们是如何分配的,但它们很可能是自动的并在堆栈上分配的。我从未见过一个实现能做任何其他事情。@truthseek。根据定义,它们是自动变量,因为对于数组,如果标识符被声明为具有静态或线程存储持续时间的对象,则它不应具有可变长度数组类型。(6.7.6.2数组声明符§2)。malloc不能申报VLA。