gpt4 book ai didi

c - 在堆栈和堆上创建的变量的生命周期之间的区别?

转载 作者:行者123 更新时间:2023-11-30 18:17:06 39 4
gpt4 key购买 nike

我知道在动态内存分配的情况下使用堆,否则使用堆栈。
我试过Difference between static memory allocation and dynamic memory allocation
我知道区别,但困惑在于他们的一生。

最佳答案

首先,栈和堆是实现细节(“栈”和“堆”这两个词没有出现在 C language standard 的任何地方)。相反,该标准讨论了对象的存储持续时间(第 6.2.4 节)。

从 C2011 开始,有四种存储持续时间:静态、自动、线程和已分配。

具有静态存储持续时间的对象的生命周期 1 会随着程序的生命周期而延长。也就是说,在加载程序时为它们留出内存,并在程序退出时释放内存。在文件范围(任何函数之外)或使用 static 声明的对象关键字具有静态存储持续时间。静态对象的存储通常是从二进制图像本身分配的(对于 ELF,这将包括 .data.rodata.bss 部分);也就是说,不是堆栈或堆的东西。

具有自动存储持续时间的对象具有从创建它们的 block 的入口到 block 退出的生命周期。如果以递归方式输入 block ,则会创建一个新对象。在没有 static 的 block 中声明的对象关键字具有自动存储期限。具有自动存储持续时间的对象通常从运行时硬件堆栈中分配,尽管并非所有架构都有堆栈。

具有线程存储持续时间的对象的生命周期会随着创建它们的线程的执行而延长。用 _Thread_local 声明的对象关键字具有线程存储持续时间。我认为线程局部对象的分配方式与自动变量相同,但这可能是错误的;我从来没有使用过 C2011 原生线程,所以我不能肯定。

具有分配存储持续时间的对象的生命周期从它们被分配的时间开始延长 malloc , calloc , 或 realloc直到通过调用 free 显式释放它们.具有分配存储持续时间的对象通常从堆中分配(尽管并非所有架构都具有这样的堆)。事情变得困惑的地方是将分配的对象与指向它的对象区分开来。给定以下代码:

int *foo( void )
{
int *bar = malloc( sizeof *bar * 10 );
// do stuff with bar
return bar;
}

void bletch( void )
{
int *blurga = foo();
// do stuff with blurga
free( blurga );
}

我们已经分配了三个对象。在函数 foo ,我们分配一个指针对象(由变量 bar 引用)具有自动存储持续时间;它的生命周期是函数的生命周期 foo .在函数 bletch ,我们分配另一个指针对象(由变量 blurga 引用)具有自动存储持续时间;它的生命周期延续到函数的生命周期 bletch .

第三个对象是一个足以容纳 10 int 的缓冲区。对象。它的生命周期从 malloc来电 foofree来电 bletch ;它的生命周期与任何函数或 block 的生命周期无关。

1. 对象的生命周期是在程序执行期间保证为该对象保留存储空间的时间。请注意,对象的生命周期与引用该对象的标识符的范围不同。尽管可以在 block 入口处为对象分配内存,但引用它的标识符的范围可能会受到更多限制。
假设以下代码:
void foo()
{
printf( "entered foo\n" );
int i = 0;
while ( i < 10 )
printf( "%d\n", i++ );
}
变量 i的作用域从其声明的末尾延伸到 block 的末尾;然而,整数对象的生命周期 i指从 block 入口延伸到 block 导出。

2. 实际上,大多数编译器都会在函数入口处为所有 block 范围变量留出存储空间,即使有些变量可能是函数内的 block 的本地变量。但是,最好假设 auto 的生命周期对象仅扩展到包含它的 block 。

关于c - 在堆栈和堆上创建的变量的生命周期之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32763595/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com