C++ 创建静态数组出现栈满程序崩溃的问题
C++ 创建静态数组出现栈满程序崩溃的问题
问题:
在C++中,在函数中创建一个比较大的数组,会导致程序崩溃无法运行。
如:
#include<iostream>
#include<vector>
const int MAX_N = 100000 + 10;
int main(){
vector<int> arr[MAX_N]; // 会导致程序根本无法运行
cout<<"I am a array"<<endl; // 这行代码更不会输出!
return 0;
}
原因解释:
数组的内存分配机制:
- 如果是静态数组,如
int arr[10]
,会直接分配在栈中,栈的空间通常很小,通常为 1~8MB栈(Stack) 是程序运行时用于存储局部变量和函数调用上下文的内存区域。它的大小通常由操作系统或编译器限制,默认栈空间很小(通常为 1 ~ 8MB)。
- 如果动态数组,如
int* arr = new int[10]
,会直接分配在堆中,堆支持动态内存扩展,就一般情况而言,堆不会出现满的状况,除非内存满了,注意:堆空间需要手动维护也就是在不适用是需要手动释放内存。
动态数组的形式:// 情况一: int* arr = (int*) malloc(sizeof(int) * 10); // 释放 free(arr) // 情况二: int* arr = (int*) new int[10]; // 释放 delete[] arr; // 情况三:(不需要手动维护) vector<int> arr(10);
- 静态数组全局定义:将静态数组定义在函数外部,此时静态数组存储的位置变为了一个全局变量,对于全局变量有:全局变量存储在数据段(Data Segment)或 BSS 段中,这些区域的内存空间远大于栈。因此,即使数组非常大(如 100,010 个元素),全局变量的内存分配也不会导致栈溢出。
- 数据段和BSS段都是用来存储全局变量和静态变量的,但根据变量是否初始化以及初始化的值来区分两者。
- 数据段用于存储已初始化的数据,而BSS段则用于存储未初始化的数据或是初始化为0的数据.这意味着BSS段比数据段更节省磁盘空间,因为它不需要存储实际的初始值,仅需记录需要多少空间来存放这些变量即可。