You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从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 &para1, nngNode &para2) {
        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 &para1, const nngNode &para2) {
        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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 05:01:19