PAT
刷题之段错误【updating…】
1.什么是段错误?
先给出一张图,所谓的段错误就是:Segmentation fault
在提交 pat 的一道题时,出现了这个段错误。其实更具体的报错是:
Program received signal SIGSEGV,Segmentation fault.
我尝试使用其它的测试用例调试时,发现的确存在这个问题,如下:
2.如何解决?
是程序存在漏洞,导致出现这个问题。常见的漏洞就是:
- 访问了不该访问的内容,导致出现这种错误。
3.示例
今天在刷pat题时,又出现了段错误。题目如下:
PAT 1117
:题目链接
这道题很简单
3.1 代码如下:
#include<cstdio>
using namespace std;
int main(){
int n ;
scanf("%d",&n);
int array[n+1];
int i = 0;
int dis;
for(i = 0;i<= n;i++){
array[i] = 0;
}
for(i = 0;i< n ;i++){
scanf("%d",&dis);
while(--dis>0 ){
array[dis]++;
}
}
for(i = n;i >= 1;i--){
if(array[i] == i){
printf("%d",array[i]);
break;
}
}
}
3.2 测试用例
3
9 9 9
使用上述的测试用例时,出现的情况如下:
即:输入数据之后,莫名卡住。而这个莫名卡住,就是因为访问了不应该访问的内存。这种问题极易出现在数组下标越界等情况。因为C++语言是没有ArrayIndexOutOfBoundsException
报的。所以只能报一个较为低级的段错误。
3.3 提交代码
3.4 修改错误
针对题目的叙述,我检查了一下问题的原因。主要是因为array[]
数组下标越界的情况导致。所以这里将 代码
while(--dis>0 ){
array[dis]++;
}
修改成
while(--dis>0 ){
if( dis<=n ) array[dis]++;
}
这样就可以避免导致 段错误 的出现了。
==== update on 2019 02 01 ===========
今天在刷题的时候,再次遇到了段错误。如下图所示:
这一题是1130,求出一个二叉树的中序遍历。【但要求是:需要输出括号】 这里不再介绍。发生段错误的原因是:
因为leftRoot
和rightRoot
值可能为-1,但是array[]
没有-1的下标。当访问array[-1]
于是就产生了段错误。修改一下代码如下:
if(leftRoot != -1) ldr(leftRoot);
cout<<n[root].data;
if(rightRoot !=-1) ldr(rightRoot);