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;
}