从priority_queue取出nngNode后出现-nan及成员值异常求助
问题描述
我用C++给自定义结构体nngNode赋值,数组计算阶段能看到正确结果,但从priority_queue取出nngNode后,ndist字段显示-nan,pixelval、pixelnum字段值也不符合预期(变为1、0)。以下是相关代码及输出结果,恳请提供排查思路或解决建议:
1. 核心代码
struct nngNode{ int x; int y; int pixelval; int pixelnum; double ndist; nngNode(int x, int y, int pixelVal,int pixelNum,double ndist) : x(x), y(y), pixelval(pixelval),pixelnum(pixelnum),ndist(ndist) {} }; struct cmp2{ bool operator()(nngNode ¶1, nngNode ¶2) { return para1.ndist > para2.ndist; } }; template<class T1> class Array2D{ public: int arows=0; int acols=0; T1** __restrict matImg; Array2D(int rows,int cols,T1 defaultVal):arows(rows),acols(cols){ matImg=new T1*[rows]; for(int i=0;i<rows;i++){ matImg[i]=new T1[cols]; memset(matImg[i],defaultVal,sizeof(T1)*cols); } } T1 &operator()(int m, const int n){ return matImg[m][n]; } T1 *operator()(int k){ return matImg[k]; } ~Array2D(){ for(int i=0;i<arows;i++){ delete[] matImg[i]; } delete [] matImg; } }; int ragNode=0; int pixelSum[id]={0}; int pixelNum[id]={0}; // 计算后pixelSum和pixelNum已有有效值 priority_queue<nngNode,vector<nngNode>,cmp2> nngprioq; Array2D<double> neighDist(id,id,0); //#pragma omp parallel for reduction(+:ragNode) for(int i=0;i<id;i++){ for(int j=0;j<id;j++){ if(idArr(i,j)==1 && pixelNum[i]>0 && pixelNum[j]>0){ ragNode++; double powerDis=pow((((double)pixelSum[i])/(double)pixelNum[i]-((double)pixelSum[j])/(double)pixelNum[j]),2); double mulelement=((double)pixelNum[i])*((double)pixelNum[j]); double divelement=(double)(pixelNum[i]+pixelNum[j]); cout<<"------------------------------------"<<endl; cout<<"powerDis:"<<powerDis<<endl; cout<<"mulelement:"<<mulelement<<endl; cout<<"divelement:"<<divelement<<endl; cout<<"("<<i<<","<<j<<")"<<endl; cout<<"psum"<<pixelSum[i]<<endl; cout<<"pnum"<<pixelNum[i]<<endl; cout<<"distance of"<<"("<<i<<","<<j<<"):"<<((mulelement*powerDis)/divelement)<<endl; neighDist(i,j)=((mulelement*powerDis)/divelement)+1.0; nngNode newnode=nngNode(i,j,pixelSum[i],pixelNum[i],neighDist(i,j)); nngprioq.push(newnode); } } }
数组阶段输出(部分)
------------------------------------ powerDis:0.681595 mulelement:47124 divelement:1711 (240,255) psum61 pnum28 distance of(240,255):18.7724 ------------------------------------ powerDis:0.425937 mulelement:26376 divelement:970 (240,268) psum61 pnum28 distance of(240,268):11.582 ------------------------------------ powerDis:4.33408 mulelement:295656 divelement:1718 (241,170) psum1055 pnum194 distance of(241,170):745.865 ------------------------------------ powerDis:8.18913 mulelement:285374 divelement:1665 (241,201) psum1055 pnum194 distance of(241,201):1403.58 ------------------------------------ powerDis:1.25224 mulelement:295462 divelement:1717 (241,247) psum1055 pnum194 distance of(241,247):215.487 ------------------------------------ powerDis:0.0334138 mulelement:25050 divelement:551 (242,219) psum129 pnum50 distance of(242,219):1.51908 ------------------------------------ powerDis:1.1664 mulelement:100 divelement:52 (242,233) psum129 pnum50 distance of(242,233):2.24308 ------------------------------------ powerDis:1.84341 mulelement:246 divelement:47 (243,251) psum122 pnum41 distance of(243,251):9.6485 ------------------------------------ powerDis:0.00629865 mulelement:46986 divelement:1187 (243,267) psum122 pnum41 distance of(243,267):0.249325 ------------------------------------ powerDis:0.0911844 mulelement:10521 divelement:522 (244,219) psum44 pnum21 distance of(244,219):1.83784 ------------------------------------
2. 优先级队列遍历代码
int ncounter=0; cout<<"---------------------nng queue---------------------------"<<endl; while(!nngprioq.empty()){ cout<<"---------------------------------------------"<<endl; cout<<ncounter<<"st Element:"<<endl; cout<<"distanceValue:"<<(double)nngprioq.top().ndist<<endl; cout<<"x:"<<nngprioq.top().x<<endl; cout<<"y:"<<nngprioq.top().y<<endl; cout<<"sumPixel:"<<nngprioq.top().pixelval<<endl; cout<<"numPixel:"<<nngprioq.top().pixelnum<<endl; nngprioq.pop(); ncounter++; }
队列输出结果(含-nan异常)
x:1 y:6 sumPixel:1 numPixel:0 --------------------------------------------- 913st Element: distanceValue:-nan x:1 y:0 sumPixel:1 numPixel:0 --------------------------------------------- 914st Element: distanceValue:-nan x:1 y:4 sumPixel:1 numPixel:0 --------------------------------------------- 915st Element: distanceValue:-nan x:0 y:26 sumPixel:1 numPixel:0 --------------------------------------------- 916st Element: distanceValue:-nan x:0 y:11 sumPixel:1 numPixel:0 --------------------------------------------- 917st Element: distanceValue:-nan x:0 y:20
排查思路与解决建议
1. 修复构造函数的初始化错误
这是导致字段值异常的核心原因:nngNode的构造函数初始化列表中,pixelval(pixelval)和pixelnum(pixelnum)是用成员变量自身初始化,而非传入的参数,导致这两个字段的值是未定义的垃圾值,进而影响ndist的后续存储或计算。
修正后的构造函数:
nngNode(int x, int y, int pixelVal,int pixelNum,double ndist) : x(x), y(y), pixelval(pixelVal), pixelnum(pixelNum), ndist(ndist) {}
2. 修正比较函数的const正确性
priority_queue内部的元素是const的,比较函数的参数必须是const引用,否则会触发未定义行为。修改cmp2:
struct cmp2{ bool operator()(const nngNode ¶1, const nngNode ¶2) { return para1.ndist > para2.ndist; } };
3. 修复Array2D类的memset误用
memset按字节赋值,对于double类型会导致值异常,改用循环赋值初始化数组:
Array2D(int rows,int cols,T1 defaultVal):arows(rows),acols(cols){ matImg=new T1*[rows]; for(int i=0;i<rows;i++){ matImg[i]=new T1[cols]; for(int j=0;j<cols;j++){ matImg[i][j] = defaultVal; } } }
4. 避免变长数组的非标准用法
C++标准不支持变长数组(int pixelSum[id]={0}中的id如果是运行时变量则属于非标准扩展),改用vector替代:
vector<int> pixelSum(id, 0); vector<int> pixelNum(id, 0);
5. 验证入队前的元素正确性
在nngprioq.push(newnode)前,打印newnode的所有字段,确认入队前值是正确的,排除队列拷贝过程中的潜在问题。
内容的提问来源于stack exchange,提问作者Lance
相关产品推荐
相关产品推荐

