c++ - 以下程序中的分段错误
问题描述
我试图解决非常基本的问题SPOJ CANDY 在提交以下解决方案时出现分段错误。但在 Visual Studio 中它工作正常。我还通过考虑大小(sum as 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 的分配。现在,“分配”是错误的词,因为它本质上只是arr
通过执行类似int * arr = STACK_POINTER-40004
.
不幸的是,默认情况下最大堆栈大小为 12 kB 是很常见的。这意味着操作系统将 12 kB 映射到内存并设置STACK_POINTER
到该内存的顶部(假设堆栈向下增长)。
所以最终效果是您的arr
指针现在指向已分配堆栈之外 - 指向未分配内存 - 并且第一次访问会引发分段错误。通常,您可以通过增加堆栈大小来解决此问题ulimit -s
,但您无法控制所使用的判断平台。
你有两个选择:
- 改用堆分配
int *arr = new int[10001]
。这不受初始堆栈大小的影响。在普通程序中,您应该注意清理它,但对于像这样的短程序,则没有必要。 - 将声明
int arr[10001]
移到顶层。arr
将指向一个称为 BSS 部分的区域,该区域最初为零。这也不受初始堆栈大小的影响。
推荐阅读
- python - 抓取维基百科
- airflow - 气流任务启动问题
- rust - 某些枚举变体未实现调试特征
- python - 将文本文件转换为键字符串和值整数的字典
- c# - 在 Wpf Datagrid 上的特定位置放置一个控件
- reactjs - 在 React 组件中使用 JS 创建具有 onClick 属性的元素以进行函数调用
- python - 如何在 2 元组集中找到具有特定第一个元素的 2 元组?
- android - XML 标记有空的正文少... (Ctrl+F1) 报告空的标记正文。验证适用于 XML / JSP / JSPX / HTML/ XHTML 文件类型
- android - 数据已插入 SQLite Android 数据库但未显示
- angular - 如何从下拉列表中设置选定的文本