非常奇怪的C++;行为 我在一个C++程序中遇到了一个非常奇怪的bug,我为学校作业写了(最后粘贴代码),我不明白为什么它要做它。特别是,它有时随机给出不正确的输出,有时给出正确的输出,每次都在相同的输入上运行。如果有人知道原因,我将非常感激: 我制作了一个C++程序,它实现了一个简单的Max HeAP数据结构,它支持使用堆插入来建立堆,一个接一个地从空堆中插入元素,或者从一个元素数组开始,在元素的前半部分使用bubbledown将其转换为一个堆——程序接受一个命令行参数,HeapInsert使用第一个方法构建堆,或者bubbledown使用第二个方法构建堆

非常奇怪的C++;行为 我在一个C++程序中遇到了一个非常奇怪的bug,我为学校作业写了(最后粘贴代码),我不明白为什么它要做它。特别是,它有时随机给出不正确的输出,有时给出正确的输出,每次都在相同的输入上运行。如果有人知道原因,我将非常感激: 我制作了一个C++程序,它实现了一个简单的Max HeAP数据结构,它支持使用堆插入来建立堆,一个接一个地从空堆中插入元素,或者从一个元素数组开始,在元素的前半部分使用bubbledown将其转换为一个堆——程序接受一个命令行参数,HeapInsert使用第一个方法构建堆,或者bubbledown使用第二个方法构建堆,c++,C++,该程序从cin中获取用户输入:首先是要生成堆的元素数,然后是要放入堆中的元素数。完成后,它输出在bubbleup/bubbledown中执行的交换次数,然后输出堆的元素,以便它们位于存储堆的数组中 我们已经得到了一个样本输入(100个随机数)和一个样本输出,我的代码应该生成这个样本输出,以便知道我们的实现是正确的。我在命令行上执行以下操作: g++ HeapTest.cpp ./a.out BubbleDown < 100.txt > out diff out s100b.txt

该程序从cin中获取用户输入:首先是要生成堆的元素数,然后是要放入堆中的元素数。完成后,它输出在bubbleup/bubbledown中执行的交换次数,然后输出堆的元素,以便它们位于存储堆的数组中

我们已经得到了一个样本输入(100个随机数)和一个样本输出,我的代码应该生成这个样本输出,以便知道我们的实现是正确的。我在命令行上执行以下操作:

g++ HeapTest.cpp
./a.out BubbleDown < 100.txt > out
diff out s100b.txt
g++HeapTest.cpp
./a.out泡泡下降<100.txt>out
差分输出s100b.txt
100.txt是样本输入,s100b.txt是正确的样本输出

执行命令行

./a.out BubbleDown < 100.txt > out
diff out s100b.txt
/a.out BubbleDown<100.txt>out
差分输出s100b.txt
我反复得到不一致的结果。似乎有一半的时间我的输出与示例文件完全匹配,但有一半的时间我的输出与示例文件不匹配,特别是当我查看我的输出文件时,它看起来像是一个随机的大数字无缘无故地插入到我的堆中,使我的输出出错

对于我来说,如果使用完全相同的输入重复运行代码,结果会不一致,这是毫无意义的。只有在命令行上使用“BubbleDown”选项时才会发生这种情况。下面是我的代码:

#include <cstdlib>
#include <stdint.h>       
#include <iostream>
#include <string>
#include <cstring>
#include <cassert>
#include <cmath>
using namespace std;

struct MaxHeap { //MaxHeap data structure
    int n;      //size of the heap
    int numex;  //number of exchanges in building the heap
    int* A;     //Array storing the actual heap
    MaxHeap(int a){     //First Constructor: initializes an empty heap of size 0 in an array of size a
        n=0;    //initialize size to 0
        numex=0;//initialize numex to 0
        A = new int[a]; //allocate space for array of size A on heap
    }
    MaxHeap(int * data, int a){ //Second Constructor: consumes array of a elements and creates a heap
                            //out of thoses elements using bubbledown
        n = a;
        A = data;
        numex = 0;

        for(int k = (int)(floor((n-1)/2)); k > -1 ; k-=1){
            bubbledown(k);
        }
    }
    ~MaxHeap(){}    //necessary since MaxHeaps made with first constructor are non-contiguous
    void bubbleup(int v){//bubble-up algorithm as described in class
        int j;
        while( (v != 0) && (A[(int)(floor((v-1)/2))] < A[v]) ){
            numex +=1;
            j = A[v];
            A[v] = A[(int)(floor((v-1)/2))];
            A[(int)(floor((v-1)/2))] = j;
            v = (int)(floor((v-1)/2));

        }

    }
    void bubbledown(int v){//bubbledown algorithm as described in calss

        int j;
        int k;
        int L;
        int temp;
        while(true){

            j = 2*v+1;
            k = 2*v+2;
            if((j <= n) && (A[j] > A[v])){L = j;}
            else{L = v;}
            if((k <= n) && (A[k] > A[L])){L = k;}
            if(L == v){break;}
            else{numex +=1; temp = A[v]; A[v] = A[L]; A[L] = temp; v=L;}
        }

    }
    void HeapInsert(int i, int k){//heapinsert algorithm as described in class

        n=k+1;
        A[n-1] = i;
        bubbleup(n-1);

    }
};

void error(){

    cerr << "Usage: " << endl;
    exit(-1);

}

int main(int argc, char * argv[]){

    int flag;
    char hins[] = "HeapInsert";
    char bdwn[] = "BubbleDown";

    switch(argc){    
        case 2:
            if(strcmp(argv[1], hins) == 0){flag=0; break;}
            else if(strcmp(argv[1], bdwn) == 0){flag=1; break;}
            else{error();}
        default: error();
    }

    if(flag==0){//If HeapInsert option selected, the below creates a heap via HeapInsert

        int nelem;
        cin >> nelem;       //read in number of elements that are going to be given
        struct MaxHeap H = MaxHeap(nelem);  //call first constructor

        for(int k=0; k < nelem; k+=1){      //insert elements into the heap one by one as they are read in
            int i;
            cin >> i;
            H.HeapInsert(i,k);
        }

        cout << H.numex << endl;            //print number of exchanges

        for(int k =0;k < nelem; k+=1){      //print elements of heap 1 by 1

            cout << H.A[k] << endl;

        }

    }
    else{       //if BubbleDown option chosen by user

        int nelem;
        cin >> nelem;   //read in number of elements
        int data[nelem];    //initialize array to store that number of elements

        for(int k=0; k < nelem; k+=1){  //build array of elements in order given

            int i;
            cin >> i;
            data[k] = i;

        }

        struct MaxHeap H = MaxHeap(data, nelem);    //use second constructor to create a heap out of the array

        cout << H.numex << endl;            //print number of exchanges

        for(int k =0;k < nelem; k+=1){      //print out elements 1 by 1

            cout << H.A[k] << endl;

        }

    }
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
struct MaxHeap{//MaxHeap数据结构
int n;//堆的大小
int numex;//构建堆时的交换数
int*A;//存储实际堆的数组
MaxHeap(inta){//First构造函数:在大小为a的数组中初始化大小为0的空堆
n=0;//将大小初始化为0
numex=0;//将numex初始化为0
A=new int[A];//为堆上大小为A的数组分配空间
}
MaxHeap(int*data,int a){//第二个构造函数:使用元素数组并创建堆
//使用bubbledown的out-of-thoses元素
n=a;
A=数据;
numex=0;
对于(int k=(int)(楼层((n-1)/2));k>-1;k-=1){
泡泡镇(k);
}
}
~MaxHeap(){}//是必需的,因为使用第一个构造函数生成的MaxHeap是非连续的
void bubbleup(int v){//bubble up算法,如类中所述
int j;
而((v!=0)和&(A[(int)(楼层((v-1)/2))]>i;
H.HeapInsert(i,k);
}
我不能;
数据[k]=i;
}
struct MaxHeap H=MaxHeap(数据,nelem)//使用第二个构造函数从数组中创建堆

我用调试符号编译了你的程序

gcc-g-O0-o stuff.cpp

然后把它放进去

echo'4233456'| valgrind./stuff BubbleDown

它是这样说的:

==28605== Conditional jump or move depends on uninitialised value(s)
==28605==    at 0x401186: MaxHeap::bubbledown(int) (stuff.cpp:52)
==28605==    by 0x400FCD: MaxHeap::MaxHeap(int*, int) (stuff.cpp:26)
==28605==    by 0x400E08: main (stuff.cpp:125)
这似乎与此相对应:

if((j <= n) && (A[j] > A[v])){L = j;}

注意:我使用了一些Linux命令来实现这一点(最重要的是Valgrind)。无论您使用的是什么编译器工具链/IDE,都应该有自己的调试器,它可能会为您提供类似的输出。有一个。我建议找一个你喜欢的工具,它会使C++调试变得更容易。

<代码> int数据[Nele];<代码>无效C++。可变长度数组不是C++的一部分,看起来是时候退出<代码> Valgnnd/Cuth>。C++中不需要说<代码>结构> /COD>,应该使用直接初始化而不是复制初始化:<代码> Max HeAPH(NelEM);<代码>(这与您的问题无关,仅与您的学习C++有关)。您也可以使用 STD::String < /Cords>,您可以直接比较。<代码> N<代码>在“代码”HeAPePosits()/Cube >中有什么意义?有些注释表示极大混淆:<代码> ~~(?)//由于使用第一个构造函数生成的maxheap是非连续的,所以必须使用该类
void bubbledown(int v){//bubbledown algorithm as described in calss
    while(true){
        const int j = 2*v+1;
        const int k = 2*v+2;
        int L;

        // notice < instead of <=
        if((j < n) && (A[j] > A[v])){
            L = j;
        }
        else{
            L = v;
        }

        // notice < instead of <=
        if((k < n) && (A[k] > A[L])){
            L = k;
        }
        if(L == v){
            break;
        }
        else{
            numex +=1;
            const int temp = A[v];
            A[v] = A[L];
            A[L] = temp;
            v = L;
        }
    }
}