1、使用堆分配
改用 malloc
或 calloc
在堆上分配大数组,堆的大小比栈更大。
#include <stdlib.h> #include <stdio.h> void largeArrayExample() { int *arr = (int *)malloc(10000000 * sizeof(int)); // 在堆上分配 if (arr == NULL) { printf("内存分配失败!\n"); return; } // 使用数组 arr[0] = 42; printf("arr[0] = %d\n", arr[0]); free(arr); // 释放内存 } int main() { largeArrayExample(); return 0; }
2、使用静态或全局变量
静态变量和全局变量存储在数据段(data segment)中,而不是栈,因此它们不会受栈大小限制。
#include <stdio.h> static int arr[10000000]; // 静态变量 void largeArrayExample() { arr[0] = 42; printf("arr[0] = %d\n", arr[0]); } int main() { largeArrayExample(); return 0; }
3、增加栈大小
在某些情况下,可以通过修改编译器或操作系统设置来增加栈大小。
1)Linux
使用 ulimit 增加栈大小。
ulimit -s unlimited
2)Windows (Visual Studio)
在项目属性中调整栈大小。
右键点击项目 -> 属性。
转到 链接器 -> 系统 -> 堆栈大小。
修改默认栈大小。
4、使用分块数组
如果大数组可以分割成更小的块,则使用多个小块数组代替单个大数组。分块数组是一种用于管理大数组或动态数据的技术,可以有效地减少内存分配的开销,同时方便对数组数据进行分块管理。分块数组通常用于实现高效的数据操作,特别是在数据量非常大或者需要频繁调整大小的场景。
#include <stdio.h> #include <stdlib.h> #define BLOCK_SIZE 100 // 每块的大小 #define TOTAL_ELEMENTS 10000 // 总的元素数量 #define BLOCK_COUNT (TOTAL_ELEMENTS / BLOCK_SIZE) // 块的数量 int main() { // 创建一个指针数组,用于存储每块的地址 int *blocks[BLOCK_COUNT]; // 为每块分配内存 for (int i = 0; i < BLOCK_COUNT; i++) { blocks[i] = (int *)malloc(BLOCK_SIZE * sizeof(int)); if (blocks[i] == NULL) { printf("Memory allocation failed for block %d\n", i); // 释放已分配的内存,避免内存泄漏 for (int j = 0; j < i; j++) { free(blocks[j]); } return 1; } } // 填充数据 for (int i = 0; i < TOTAL_ELEMENTS; i++) { int block_index = i / BLOCK_SIZE; // 第几块 int offset = i % BLOCK_SIZE; // 块内偏移 blocks[block_index][offset] = i; // 存储数据 } // 读取和打印数据 for (int i = 0; i < TOTAL_ELEMENTS; i++) { int block_index = i / BLOCK_SIZE; // 第几块 int offset = i % BLOCK_SIZE; // 块内偏移 printf("%d ", blocks[block_index][offset]); if (i % 1000 == 999) { // 每 1000 个元素换行 printf("\n"); } } // 释放内存 for (int i = 0; i < BLOCK_COUNT; i++) { free(blocks[i]); } return 0; }