求助 RE
  • 板块灌水区
  • 楼主LittleYang0531
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/6/8 11:33
  • 上次更新2023/10/27 23:45:07
查看原帖
求助 RE
185758
LittleYang0531楼主2022/6/8 11:33

有一份代码,里面使用了优先队列,然后出现了奇怪的 RE 错误

源代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long van;
template<typename T> inline
void read(T& x) {
	T f=1,b=0; char ch=getchar();
	while (!isdigit(ch)) {
		if (ch=='-') f=-1;
		ch=getchar();
	} while (isdigit(ch))
		b*=10,b+=ch-'0',ch=getchar();
	x=f*b; return;
}
template<typename T> inline
void print(T x) {
	if (x<0) putchar('-'),x=-x;
	if (x==0) return putchar('0'),void();
	van st[51]={0},k=0;
	while (x) st[++k]=x%10,x/=10;
	for (int i=k;i;i--) putchar(st[i]+'0');
} const van MaxN=50;
van p[MaxN],n,m,k,h;
char maze[MaxN][MaxN]; van g[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
van order[6]; bool used[MaxN];
van ans=0; bool dfs_used[31][31];
van stx,sty; vector<pair<van,van> > en,elem[6];
bool in(van x,van y) {
	return x>0&&y>0&&x<=n&&y<=m;
}
bool DFS(van status,char goal,van x,van y) {
	dfs_used[x][y]=1;
	for (int i=0;i<4;i++) {
		van xx=x+g[i][0],yy=y+g[i][1];
		if (!in(xx,yy)) continue;
		if (dfs_used[xx][yy]) continue;
		if (maze[xx][yy]==goal) return true;
		if (maze[xx][yy]=='#') continue;
		van id=maze[xx][yy]-'A';
		if ((status&(1<<id))==0&&maze[xx][yy]>='A'&&maze[xx][yy]<='Z') continue;
		if (DFS(status,goal,xx,yy)) return true;
	} return false;
}
bool judge_accepted() {
	van now=0; for (int i=1;i<=k;i++) {
		memset(dfs_used,0,sizeof dfs_used);
		if (!DFS(now,order[i]+'A'-1,stx,sty)) return false;
		now|=(1<<(order[i]-1));
	} return true;
}
van dis[MaxN][MaxN]; bool dijk_used[31][31];
priority_queue<pair<van,pair<van,van> > > q;
van Dijkstra(van status,van harm,van goal,van lst) {
	vector<van> d; assert(q.size()==0);
	if (lst!=-1) for (int i=0;i<elem[lst].size();i++) {
		van x=elem[lst][i].first,y=elem[lst][i].second;
		d.push_back(dis[x][y]);
	} memset(dijk_used,0,sizeof dijk_used);
	for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) dis[i][j]=-1e18;
	if (lst==-1) {
		dis[stx][sty]=h;
		q.push(make_pair(h,make_pair(stx,sty)));
	} else for (int i=0;i<elem[lst].size();i++) {
		if (d[i]==-1e18) continue;
		van x=elem[lst][i].first,y=elem[lst][i].second;
		q.push(make_pair(d[i],make_pair(x,y))); 
	} while (!q.empty()) {
		van nowx=q.top().second.first,nowy=q.top().second.second;
		van nowh=q.top().first; q.pop();
		if (dijk_used[nowx][nowy]) continue;
		dijk_used[nowx][nowy]=1;
		for (int i=0;i<4;i++) {
			van xx=nowx+g[i][0],yy=nowy+g[i][1];
			if (!in(xx,yy)) continue;
			if (maze[xx][yy]=='#') continue;
			van id=maze[xx][yy]-'A';
			if ((status&(1<<id))==0&&maze[xx][yy]!=goal+'A'&&
				maze[xx][yy]>='A'&&maze[xx][yy]<='Z') continue;
			van nxth=nowh-((harm&(1<<id))!=0);
			if (nxth>dis[xx][yy]) {
				dis[xx][yy]=nxth;
				if (maze[xx][yy]==goal+'A') continue;
				q.push(make_pair(nxth,make_pair(xx,yy)));
			}
		}
	} van l=-1e18;
	for (int i=0;i<elem[goal].size();i++) {
		van x=elem[goal][i].first,y=elem[goal][i].second;
		l=max(l,dis[x][y]);
	} return l;
}
bool is_ok(van harm) {
	van now=0; for (int i=1;i<=k;i++) {
		van lsth=Dijkstra(now,harm,order[i]-1,order[i-1]-1);
		for (int j=0;j<en.size();j++) {
			van x=en[j].first,y=en[j].second;
			if (dis[x][y]>0) return true;
		} now|=(1<<(order[i]-1)); 
	} Dijkstra(now,harm,0,order[k]-1);
	for (int i=0;i<en.size();i++) {
		van x=en[i].first,y=en[i].second;
		if (dis[x][y]>0) return true;
	} return false;
}
void solver() {
	van tmp=0;
	if (!judge_accepted()) return;
	for (int i=0;i<(1<<k);i++) {
		bool x=is_ok(i); 
		if (x) tmp+=p[i];
	} ans=max(ans,tmp);
}
void status_counter(van now=1) {
	if (now>k) return solver(),void();
	for (int i=1;i<=k;i++) {
		if (used[i]) continue;
		order[now]=i; used[i]=1;
		status_counter(now+1); 
		used[i]=0; order[now]=0;
	}
}
int main() {
	read(n),read(m),read(k),read(h);
	for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) cin>>maze[i][j];
	for (int i=0;i<(1<<k);i++) read(p[i]);
	for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) {
		if (maze[i][j]=='$') stx=i,sty=j;
		if (maze[i][j]=='@') en.push_back(make_pair(i,j));
		if (maze[i][j]=='#') continue;
		elem[maze[i][j]-'A'].push_back(make_pair(i,j));
	} status_counter(); van S=0;
	for (int i=0;i<(1<<k);i++) S+=p[i];
	printf("%.3f\n",double(ans)/double(S));
	return 0;
}

在样例较小的时候会爆出如下错误:

(gdb) r
Starting program: /home/littleyang0531/maze
munmap_chunk(): invalid pointer

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007fff7faea859 in __GI_abort () at abort.c:79
#2  0x00007fff7fb5529e in __libc_message (action=action@entry=do_abort,
    fmt=fmt@entry=0x7fff7fc7f298 "%s\n") at ../sysdeps/posix/libc_fatal.c:155
#3  0x00007fff7fb5d32c in malloc_printerr (
    str=str@entry=0x7fff7fc811e0 "munmap_chunk(): invalid pointer") at malloc.c:5347
#4  0x00007fff7fb5d57c in munmap_chunk (p=<optimized out>) at malloc.c:2830
#5  0x0000555555558b6a in __gnu_cxx::new_allocator<std::pair<long long, long long> >::deallocate (this=0x5555555601c0 <elem>, __p=0x555555578350)
    at /usr/include/c++/9/ext/new_allocator.h:128
#6  0x0000555555557d8c in std::allocator_traits<std::allocator<std::pair<long long, long long> > >::deallocate (__a=..., __p=0x555555578350, __n=2)
    at /usr/include/c++/9/bits/alloc_traits.h:469
#7  0x0000555555557220 in std::_Vector_base<std::pair<long long, long long>, std::allocator<std::pair<long long, long long> > >::_M_deallocate (
    this=0x5555555601c0 <elem>, __p=0x555555578350, __n=2)
    at /usr/include/c++/9/bits/stl_vector.h:351
#8  0x0000555555556b24 in std::_Vector_base<std::pair<long long, long long>, std::allocator<std::pair<long long, long long> > >::~_Vector_base (
    this=0x5555555601c0 <elem>, __in_chrg=<optimized out>)
    at /usr/include/c++/9/bits/stl_vector.h:332
#9  0x0000555555556b79 in std::vector<std::pair<long long, long long>, std::allocator<std::pair<long long, long long> > >::~vector (this=0x5555555601c0 <elem>,
    __in_chrg=<optimized out>) at /usr/include/c++/9/bits/stl_vector.h:680
#10 0x0000555555556845 in __tcf_0 () at maze.cpp:26
#11 0x00007fff7fb0e8d7 in __run_exit_handlers (status=0,
    listp=0x7fff7fcb4718 <__exit_funcs>,
    run_list_atexit=run_list_atexit@entry=true, run_dtors=run_dtors@entry=true)
    at exit.c:108
#12 0x00007fff7fb0ea90 in __GI_exit (status=<optimized out>) at exit.c:139
#13 0x00007fff7faec0ba in __libc_start_main (main=0x555555556474 <main()>, argc=1,
    argv=0x7fffffffe4e8, init=<optimized out>, fini=<optimized out>,
    rtld_fini=<optimized out>, stack_end=0x7fffffffe4d8) at ../csu/libc-start.c:342
#14 0x000055555555528e in _start ()

最后的结果是能出正确结果但是在最后 RE 了,GDB 并没有返回任何与源代码有关的错误(但还是隐隐约约能够看出是和优先队列有关的错误)

在样例较大的时候会爆出如下错误:

(gdb) r
Starting program: /home/littleyang0531/maze
maze: malloc.c:2379: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007fff7faea859 in __GI_abort () at abort.c:79
#2  0x00007fff7fb5d30a in __malloc_assert (
    assertion=assertion@entry=0x7fff7fc818a8 "(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)",
    file=file@entry=0x7fff7fc7d3d6 "malloc.c", line=line@entry=2379,
    function=function@entry=0x7fff7fc82030 <__PRETTY_FUNCTION__.13066> "sysmalloc")
    at malloc.c:298
#3  0x00007fff7fb5f96f in sysmalloc (nb=nb@entry=32,
    av=av@entry=0x7fff7fcb4b80 <main_arena>) at malloc.c:2379
#4  0x00007fff7fb607c3 in _int_malloc (av=av@entry=0x7fff7fcb4b80 <main_arena>,
    bytes=bytes@entry=24) at malloc.c:4141
#5  0x00007fff7fb62184 in __GI___libc_malloc (bytes=24) at malloc.c:3058
#6  0x00007fff7fd7fb39 in operator new(unsigned long) ()
   from /lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x000055555555a2cf in __gnu_cxx::new_allocator<std::pair<long long, std::pair<long long, long long> > >::allocate (this=0x555555565460 <q>, __n=1)
    at /usr/include/c++/9/ext/new_allocator.h:114
#8  0x0000555555559f1a in std::allocator_traits<std::allocator<std::pair<long long, std::pair<long long, long long> > > >::allocate (__a=..., __n=1)
    at /usr/include/c++/9/bits/alloc_traits.h:443
#9  0x0000555555559afa in std::_Vector_base<std::pair<long long, std::pair<long long, long long> >, std::allocator<std::pair<long long, std::pair<long long, long long> > > >::_M_allocate (this=0x555555565460 <q>, __n=1)
    at /usr/include/c++/9/bits/stl_vector.h:343
#10 0x0000555555558e95 in std::vector<std::pair<long long, std::pair<long long, long long> >, std::allocator<std::pair<long long, std::pair<long long, long long> > > >::_M_realloc_insert<std::pair<long long, std::pair<long long, long long> > > (
    this=0x555555565460 <q>,
    __position=non-dereferenceable iterator for std::vector)
    at /usr/include/c++/9/bits/vector.tcc:440
#11 0x00005555555582b4 in std::vector<std::pair<long long, std::pair<long long, long long> >, std::allocator<std::pair<long long, std::pair<long long, long long> > > >::emplace_back<std::pair<long long, std::pair<long long, long long> > > (
    this=0x555555565460 <q>) at /usr/include/c++/9/bits/vector.tcc:121
#12 0x000055555555793a in std::vector<std::pair<long long, std::pair<long long, long long> >, std::allocator<std::pair<long long, std::pair<long long, long long> > > >::push_back (this=0x555555565460 <q>, __x=...)
    at /usr/include/c++/9/bits/stl_vector.h:1201
#13 0x0000555555556ee8 in std::priority_queue<std::pair<long long, std::pair<long lon--Type <RET> for more, q to quit, c to continue without paging--
g, long long> >, std::vector<std::pair<long long, std::pair<long long, long long> >, std::allocator<std::pair<long long, std::pair<long long, long long> > > >, std::less<std::pair<long long, std::pair<long long, long long> > > >::push (
    this=0x555555565460 <q>, __x=...) at /usr/include/c++/9/bits/stl_queue.h:637
#14 0x000055555555598a in Dijkstra (status=0, harm=0, goal=0, lst=-1) at maze.cpp:61
#15 0x0000555555556115 in is_ok (harm=0) at maze.cpp:93
#16 0x000055555555633f in solver () at maze.cpp:109
#17 0x00005555555563c9 in status_counter (now=4) at maze.cpp:115
#18 0x000055555555643b in status_counter (now=3) at maze.cpp:119
#19 0x000055555555643b in status_counter (now=2) at maze.cpp:119
#20 0x000055555555643b in status_counter (now=1) at maze.cpp:119
#21 0x0000555555556778 in main () at maze.cpp:132

这次是连结果都不出了,而且 GDB 明显指向了优先队列插入时的错误

还有在开 O2 运行的时候并没有任何问题

求助这种问题如何解决(我的代码并不是原题的正解代码)

如果有需要,原题链接: P2489

2022/6/8 11:33
加载中...