栈上变量
- 生命周期特点:
- 栈上变量(局部变量)的生命周期与其所在函数或代码块紧密相关。当函数或代码块被进入时,栈上变量被创建并分配内存,当函数或代码块执行结束时,这些变量自动被销毁,其所占用的内存被释放。
- 示例:
#include <iostream>
void testFunction() {
int localVar = 10; // 栈上变量
std::cout << "localVar: " << localVar << std::endl;
} // 函数结束,localVar被销毁
int main() {
testFunction();
// 这里无法访问localVar,因为它已经被销毁
return 0;
}
堆上变量
- 生命周期特点:
- 堆上变量通过
new
关键字分配内存来创建,其生命周期由程序员手动控制。一旦通过new
创建,它会一直存在于内存中,直到程序员使用delete
关键字释放其占用的内存。如果不及时释放,会导致内存泄漏。
- 示例:
#include <iostream>
int main() {
int* heapVar = new int(20); // 堆上变量
std::cout << "heapVar: " << *heapVar << std::endl;
// 业务逻辑
delete heapVar; // 手动释放堆上内存
// 如果忘记这一步,heapVar占用的内存将不会被释放,造成内存泄漏
return 0;
}
全局静态存储区变量
- 生命周期特点:
- 全局变量和静态局部变量都存储在全局静态存储区。全局变量在程序启动时创建并分配内存,直到程序结束才被销毁。静态局部变量在第一次进入其所在函数时创建并初始化,之后每次进入该函数时不再重新创建,直到程序结束时才被销毁。
- 示例:
#include <iostream>
// 全局变量
int globalVar = 30;
void testFunction() {
static int staticLocalVar = 40; // 静态局部变量
std::cout << "staticLocalVar: " << staticLocalVar << std::endl;
staticLocalVar++;
}
int main() {
std::cout << "globalVar: " << globalVar << std::endl;
for (int i = 0; i < 3; ++i) {
testFunction();
}
// 程序结束时,globalVar和staticLocalVar才被销毁
return 0;
}
生命周期差异带来的影响
- 栈上变量:
- 优点是创建和销毁效率高,因为其内存管理由系统自动完成,不需要额外的函数调用开销。适用于函数内部临时使用的变量,如循环计数器、临时计算结果等。
- 缺点是作用域有限,一旦函数结束就无法访问,并且栈的空间有限,如果在栈上分配大量数据,可能导致栈溢出。
- 堆上变量:
- 优点是生命周期灵活,可以在程序的不同部分创建和释放,适用于需要动态分配内存的场景,如动态数组、链表等数据结构。
- 缺点是需要手动管理内存,增加了编程的复杂性,容易导致内存泄漏和悬空指针等问题。
- 全局静态存储区变量:
- 优点是作用域广,在整个程序中都可以访问,并且生命周期长,适用于需要在程序运行期间一直存在且保持数据一致性的场景,如记录程序运行状态的全局变量、单例模式中的实例等。
- 缺点是由于其生命周期长,可能会占用过多的内存资源,而且由于其作用域广,可能会导致命名冲突和代码维护困难,因为任何部分的代码都可以修改这些变量的值。