如何解决C++代码中出现的Segmentation Fault(段错误)问题
问题代码复现
void rearrange(long long *arr, int n) { long long temp[n]; int max = n-1; int min = 0; for(int i=0;i<n;i++){ if(i%2 == 0){ temp[i] = arr[max]; max--; } else{ temp[i] = arr[min]; min++; } } for(int i=0;i<n;i++){ arr[i] = temp[i]; } }
段错误触发原因
- 核心原因是使用了C++标准不支持的变长数组(VLA):
long long temp[n]中的n是运行时传入的参数,属于动态长度,C++标准要求数组长度必须是编译期常量。这种写法是部分编译器(如GCC)的扩展特性,数组会分配在程序栈空间,而栈空间通常只有几MB,当n的数值较大时会直接触发栈溢出,导致段错误。 - 次要排查点:如果传入的
arr是空指针、或者n的数值大于arr实际的元素个数,也会出现越界访问触发段错误。
修复方法
方案1:改用堆空间存储临时数组(标准C++兼容写法)
将临时数组替换为std::vector,内存分配在堆上,不受栈空间大小限制,同时兼容所有标准C++编译器,修改后代码如下:
#include <vector> void rearrange(long long *arr, int n) { std::vector<long long> temp(n); int max_idx = n-1; int min_idx = 0; for(int i=0;i<n;i++){ if(i%2 == 0){ temp[i] = arr[max_idx]; max_idx--; } else{ temp[i] = arr[min_idx]; min_idx++; } } for(int i=0;i<n;i++){ arr[i] = temp[i]; } }
方案2:原地修改(无需额外空间,可选优化)
如果不想申请额外内存,可以利用数值存储技巧原地修改,适合内存受限的场景:
实现逻辑:当数组元素均为非负整数时,可以将新值和旧值存储在同一个位置,遍历完成后再统一取出新值,避免申请临时数组。
void rearrange(long long *arr, int n) { int max_idx = n-1; int min_idx = 0; long long max_val = arr[max_idx] + 1; for(int i=0;i<n;i++){ if(i%2 == 0){ arr[i] += arr[max_idx] % max_val * max_val; max_idx--; } else{ arr[i] += arr[min_idx] % max_val * max_val; min_idx++; } } for(int i=0;i<n;i++){ arr[i] /= max_val; } }
内容的提问来源于stack exchange,提问作者Abhilash Singh
相关产品推荐
相关产品推荐

