问题历史:
堆栈内存在所有主要架构中都存在。在C语言中,自动(局部)变量放置在堆栈上,确保比动态堆内存更高的分配和释放速度。
问题:
堆栈的大小是有限的,自动变量在出块后会自动销毁,而堆栈溢出(stack overflow)会导致程序崩溃或数据损坏。
解决方案:
在没有特殊修饰符的情况下,函数内部声明的局部变量放置在堆栈上。此自动存储区域在进入函数时创建,退出时销毁。堆栈的大小是有限的,仅能通过链接器/系统选项更改。
代码示例:
#include <stdio.h> void foo() { int arr[100]; // 放置在堆栈上 for (int i = 0; i < 100; ++i) arr[i] = i; printf("第一个元素: %d\n", arr[0]); } // arr在退出foo后被销毁
关键特性:
可以通过地址返回局部变量吗?
不可以,因为变量在函数退出后被销毁,产生的“悬挂指针”会导致未定义行为。
int* bad() { int x = 42; return &x; // 错误:返回的指针指向被释放的堆栈 }
在堆栈上放置大数组(例如,1MB)是否可能?
对于大多数系统来说,堆栈是有限的(几十到几百KB)。尝试在堆栈上声明巨大的数组会导致堆栈溢出。
静态变量和自动变量放置的区别是什么?
静态变量(即使在函数中)被放置在静态内存区域,在调用之间不会被清除,而自动变量则放在堆栈上,在退出块时被销毁。
在函数中为计算分配了8192*1024的双精度数组在堆栈上。程序在Linux中启动时收到SIGSEGV,尽管编译没有错误。
优点:
缺点:
对于大型缓冲区,使用通过malloc/free进行动态内存分配。在堆栈上仅放置小的工作变量。
优点:
缺点: