以下程序中的分段错误

Segmentation fault in below program

本文关键字:分段 错误 程序      更新时间:2023-10-16

我试图解决非常基本的问题SPOJ CANDY我在提交以下解决方案时遇到了分段错误。但在Visual Studio中,它运行良好。我还通过考虑大小(sum等于long-long-int)来声明变量因为它可以是大型

1) 是因为我在while循环中声明了数组吗;我是否应该在while循环之外声明该数组,以便在每个测试用例中都使用相同的数组

2) 每次循环运行时(对于每个测试用例)都会创建新的数组,这会导致垃圾收集吗?还是编译器会在每个测试用例后自动释放内存(我知道在这种情况下动态内存分配,我们必须显式释放内存)?你能告诉我在哪个范围内应该声明变量吗?

我有上述疑虑,因为分段错误是关于内存访问的。

#include<iostream>
using namespace std;

int main(){
while(1){
int n;
int arr[10001];
cin>>n;
if(n==-1)
break;
long long int sum=0;
for(int i=0;i<n;i++){
int temp;
cin>>temp;
sum+=temp;
arr[i]=temp;
}
int mean=sum/n;
if((sum%n)!=0){
cout<<-1<<endl;
continue;
}
int count1=0;
for(int i=0;i<n;i++){
if(arr[i]>mean){
count1+=(arr[i]-mean);
}
}
cout<<count1<<endl;
}
}

您的问题可能是由于int arr[10001]的堆栈分配造成的。这很可能是40kB的分配。现在,"allocation"这个词是错误的,因为它本质上只是通过执行类似int * arr = STACK_POINTER-40004的操作来计算arr的地址。

不幸的是,默认情况下,最大堆栈大小通常为12kB。这意味着操作系统将12kB映射到内存中,并将STACK_POINTER设置到该内存的顶部(假设堆栈向下增长)。

因此,净效果是arr指针现在指向已分配堆栈之外的未分配内存,第一次访问会抛出分段错误。通常情况下,您可以通过使用ulimit -s增加堆栈大小来解决此问题,但您无法控制所使用的判断平台。

你有两个选择:

  • 使用堆分配,而不是int *arr = new int[10001]。这不受初始堆栈大小的影响。在一个正常的程序中,你应该注意清理它,但对于这样的短程序来说,这是没有必要的
  • int arr[10001]的声明移动到顶级。arr将指向一个称为BSS部分的区域,该区域最初为零。这也不受初始堆栈大小的影响