Runtime Error:Segmentation fault 如何找出问题所在

C++语言 码拜 6年前 (2015-05-11) 580次浏览 0个评论
 

Runtime Error:Segmentation fault
辅助解释:
Segmentation fault:段错误,检查是否有数组越界,指针异常,访问到不应该访问的内存区域

oj时出现上述错误,在VS2013中正常运行,也没有warning,不知问题在哪里或者可能在哪里?

引用

输入
第一行输入T,表示有T组测试数据(T<=5)
接下来一行输入整数n,代表有n个区间(0=<n<=10^5)
接下来n行,每行输入三个整数x,y,id.代表区间[x,y]所对应的城市ID。数据确保任意俩个区间交集为空,且ID唯一。(0=<x<y<=10^8 , 0=<ID<=10^8)
接下来一行输入整数m,代表m次查询(0=<m<=10^5)
接下来m行,每行输入一个整数V,代表所查询的IP(V<=10^8)
输出
对于每次查询,输出一行,表示其对应的城市ID。
如果未找到,输出-1

#include <iostream>
#include <vector>
using namespace std;
class ip
{
public:
	int m;
	ip() :id(3){}
	void save();	//一边插入一边排序
	long long int search(long long int V);	//找V所在ID
private:
	int T, n;
	vector<vector<long long int> > id;
	long long int dich(int left, int right,long long int V);	//二分法定位
};

void ip::save()
{
	cin >> T >> n;
	long long int a, b, Id;
	int j;
	for (int i = 0; i < n; ++i)
	{
		cin >> a >> b >> Id;
		id[0].push_back(a);
		id[1].push_back(b);
		id[2].push_back(Id);
		for (j = i; j >0 && id[0][j-1]>a; --j)
		{
			id[0][j] = id[0][j - 1];
			id[1][j] = id[1][j - 1];
			id[2][j] = id[2][j - 1];
		}
		id[0][j] = a;
		id[1][j] = b;
		id[2][j] = Id;
	}
	cin >> m;
}

long long int ip::search(long long int V)
{
	if (long long int x=dich(0, n-1,V)) return x;
	else return -1;
}

long long int ip::dich(int left, int right,long long int V)
{
	if (V<id[0][left] || V > id[1][right])
		return -1;
	int mid;
	mid = (left + right) / 2;
	if (V >= id[0][mid] && V <= id[1][mid])
		return id[2][mid];
	else if (V < id[0][mid])
		return dich(left, mid, V);
	else
		return dich(mid + 1, right, V);
}

int main()
{
	ip ip_s;
	long long int v;
	ip_s.save();
	for (int i = ip_s.m; i > 0; --i)
	{
		cin >> v;
		cout << ip_s.search(v) << endl;
	}
	return 0;
}
看了半天,木有看出来哪里有问题,楼主有测试数据吗
5分
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。
引用 1 楼 hnwyllmm 的回复:

看了半天,木有看出来哪里有问题,楼主有测试数据吗

样例输入
1
2
3 5 99
1 2 77
3
1
3
9
样例输出
77
99
-1 

这个是给的测试数据

引用 2 楼 zhao4zhong1 的回复:

崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。

这个是在VS里面的操作还是?主要是在VS中运行完全正确,不会崩溃。但是提交会显示上述错误。
OJ应该是Linux操作系统及GCC/G++编译器
是必须要在LINUX下调试么?

我在自己的环境测试,也没有问题,最少楼主给出来的测试用例是没问题的,估计是特殊的测试才会出现问题

引用 3 楼 m_scorpio 的回复:
Quote: 引用 1 楼 hnwyllmm 的回复:

看了半天,木有看出来哪里有问题,楼主有测试数据吗

样例输入
1
2
3 5 99
1 2 77
3
1
3
9
样例输出
77
99
-1 

这个是给的测试数据

30分
long long int ip::search(long long int V)
{
    if (long long int x=dich(0, n-1,V)) return x;
    else return -1;
}

如果查出来ID正好是0,楼主岂不是直接返回-1?
虽然这个不是楼主想说的那个问题吧,但是我看到了不说出来也痒痒

5分
段错误,这个应该是linux下遇到的吧?
难道没有coredump嘛?用gdb可以详细定位问题行啊
引用 6 楼 hnwyllmm 的回复:

long long int ip::search(long long int V)
{
    if (long long int x=dich(0, n-1,V)) return x;
    else return -1;
}

如果查出来ID正好是0,楼主岂不是直接返回-1?
虽然这个不是楼主想说的那个问题吧,但是我看到了不说出来也痒痒

这个问题的确是个bug。后面自己又写了个map的省事一些而且避免了这个问题。
但是map写的依然不对啊啊啊啊

后面跟提供的代码作比较,发现确实是个别测试用例会出问题,没有考虑到的就是:
如果n输入的是0,即没有创建vector/map,后面查询的时候就会报错debug assertion failed。

上面两位说的linux下的查错方法没有去试,不过我想即使是在linux下,由于没有考虑到n=0这一测试用例,恐怕也难以找到问题所在,还是感谢~~

感觉自己还是得有空好好用linux

把自己写的map版的也放过来~~
已经加上了n==0的条件判断

#include <iostream>
#include <map>
#include <utility>
using namespace std;
typedef long long int lli;

struct st
{
	lli x, y;
	st() :x(0), y(0){}
	st(lli a, lli b) :x(a), y(b){}
	friend bool operator < (const struct st &ls, const struct st &rs);
};

inline bool operator < (const struct st &ls, const struct st &rs)
{
	return (ls.x < rs.x  && ls.y < rs.y);
}

lli search(lli x, const map<st, lli> &id)
{
	st tmp = st(x, x);
	auto it = id.find(tmp);
	if (it == id.end())
		return -1;
	else
		return it->second;
}


int main()
{
	int T;
	unsigned int n,m;
	st key;
	lli ID, V;
	map<st, lli> id;

	cin >> T;
	for (; T > 0; --T)
	{
		cin >> n;
		for (unsigned int i=n; i>0; --i)
		{
			cin >> key.x >> key.y >> ID;
			id.insert(pair<st, lli>(key, ID));
		}

		cin >> m;
		for (; m > 0; --m)
		{
			cin >> V;
			if (n == 0)
				cout << "-1" << endl;
			else
				cout << search(V, id) << endl;
		}
	}
	return 0;
}
inline bool operator < (const struct st &ls, const struct st &rs)
{
    return (ls.x < rs.x  && ls.y < rs.y);
}
哈哈,楼主你这个写的有问题
不是应该这样吗:
return ls.x < rs.x || (ls.x == rs.x && ls.y < rs.y)
Linux:
进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’
使用命令
gdb 运行程序名 core或core.数字
进入gdb然后使用bt命令
可以查看进程意外退出前函数调用的堆栈,内容为从上到下列出对应从里层到外层的函数调用历史。
如果进程意外退出不产生core文件,参考“ulimit -c core文件最大块大小”命令

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明Runtime Error:Segmentation fault 如何找出问题所在
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!