在C语言中,什么时候分配和取消分配静态和动态内存?

在C语言中,什么时候分配和取消分配静态和动态内存?,c,memory,memory-management,C,Memory,Memory Management,我现在正在学习C,并试图弄清楚C的内存管理是如何工作的。如果我错了,请纠正我,但我知道: 静态内存分配-这发生在编译时。编译器分配静态内存所需的必要内存 静态内存释放-当块/函数完成运行(对于局部变量)或整个程序完成执行(对于全局变量)时,内存将自动释放 动态内存分配-内存是在运行时分配的,因为此时输入的大小未知 Dynamics memory deallocation—执行free()时内存被释放 这是对的吗?我遗漏了什么吗?C语言中有3种不同的存储持续时间: 静态:变量的生存期就是程序的生

我现在正在学习C,并试图弄清楚C的内存管理是如何工作的。如果我错了,请纠正我,但我知道:

静态内存分配-这发生在编译时。编译器分配静态内存所需的必要内存

静态内存释放-当块/函数完成运行(对于局部变量)或整个程序完成执行(对于全局变量)时,内存将自动释放

动态内存分配-内存是在运行时分配的,因为此时输入的大小未知

Dynamics memory deallocation—执行free()时内存被释放


这是对的吗?我遗漏了什么吗?

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。