vendredi 16 mars 2018

Mem Leak? C++11 intermittent jumping out of a loop and hanging up at runtime w no compiler warnings or runtime errors

I am hardware engineer and C++ Noob, very experienced in VHDL (which seems to be exacerbating my difficulties in picking up C++.)
The description of my code is in the header, but I'll explain some here. I'm using C++ 11. I am just learning these debuggers, but I set as couple of breakpoints and SS'd and narrowed it down. I seem to be jumping out into the weeds intermittently inside the if-then-else in the inner while loop of this code. The code just makes a class for a pixel (a pair of integers) overloads the +, - == and != operators and then generates random pairs and stuffs them in a vector. When the random pair is generated it needs to be unique, so it checks the values in the vector to see if it exists already. If it does, then a new pair is generated and checked again. until complete. I have the size small right now (N=10), but it will be orders of magnitude bigger when in use. I tried this on Netbeans and CLion with similar results. Please excuse the verbose commenting and cout statements I have in there for debugging. Keep in mind that I'm a noob in C++, but not in EE. Let me know if I violated form in this forum and I'll correct my question.

/*
 * Create a class for an integer pair to be used for various video projects or a 
 * general purpose 2-d point. Can be used .  This code is designed to be used in 
 * an HLS tool to be synthesized into hardware on an FPGA.  Recursion and memory 
 * allocation is illegal, but since I can use this in a test bench  I'll 
 * ignore the memory allocation dealt with in the vector STL.  I also use random
 * number stuff which will be dealt with differently in the synthesized code.
 * 
 * In this project I'm creating a vector of random unique pixels  
 */

/* 
 * File:   main.cpp
 * Author: pj
 * Created on March 15, 2018, 10:00 PM
 */
#include <iostream>
#include <cmath>
#include<vector>
#include<random>
#include<cstdlib>

using namespace std;

const int N = 10;  //Global constant for number of pairs

// Pixel class tuple of 2-elements (x,y).  Could be a pixel on a monitor just a 
// point the Cartesian plane

class pixel {

private:

    int x;
    int y;

public:

    // pixel(int x = 0, int y = 0):x(x),y(y){} // constructor

    // required constructors.  This was necessary to do the comparison
    // operator overloading.  I'm not sure why.
    pixel() {
        x = 0;
        y = 0;
    }
    pixel(int u, int v) {
        x = u;
        y = v;
    }

    // ~pixel();

       // Class members
    int Getx(){return x;}
    int Gety(){return y;}
    void Set(int x, int y){this->x = x; this->y = y;}

    //Operator Overloders
    pixel operator+(const pixel &) const; // operator+()
    pixel operator-(const pixel &) const; // operator-()
    bool operator!=(const pixel &) const; // operator !=(not equal to)
    bool operator==(const pixel &) const; // operator==(equal to)

    // ostream overloader must be declared a friend of the class to access 
    //private memebers
    friend ostream&  operator<<(ostream &out,const pixel &p);

};

ostream& operator<<(ostream &out, const pixel &p) {
    out <<"("<< p.x << ',' << p.y <<")"<< endl;

    return out;
}

// define overloaded + (plus) operator
pixel pixel::operator+(const pixel& c) const
{
    pixel result;
    result.x = (this->x + c.x);
    result.y = (this->y + c.y);
    return result;
}

// define overloaded - (minus) operator
pixel pixel::operator-(const pixel& c) const
{
    pixel result;
    result.x = (this->x - c.x);
    result.y = (this->y - c.y);
    return result;
}

// define overloaded != (not equal) operator
bool pixel::operator!=(const pixel &c) const {
    {
        if((this->x != c.x) && (this->y != c.y))
            return true;
    }
    return false;
}

// define overloaded == (equal) operator
bool pixel::operator==(const pixel &c) const {
    {
        if((this->x == c.x) && (this->y == c.y))
            return true;
    }
    return false;
}


int main() {

    int x, y;
    int CheckCnt = 0;
    int NodeCnt = 0;
    int dupliCount = 0;
    int EdgeWeight;

    pixel pt, pti, ptn;

    // pixel NodeList[N] declaration;
    vector<pixel> NodeList(N);    // Vector of N points init to 0
    pixel *p = NodeList.data();  // set a ptr to pixel to the base loc of NodeList

    //Random int generator
    std::random_device rd;  //Will be used to obtain a seed for the random number engine
    std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
    std::uniform_int_distribution<> dis(0, N);

    // Generate pixel 0
    x = dis(gen); //
    y = dis(gen); // generate a random pt
    pt.Set(x, y); //
    *p = pt;  //put node 0 in the Nodelist
    // ostream overload can't handle the pixel vector element reference
    // a temp value for pixel is assigned for display purposes
    ptn = NodeList[NodeCnt];
    cout << "Node(" << NodeCnt << ") = " << ptn << endl;
    ++p;           // advance ptr to next NodeList location
    NodeCnt = 1;   //Node is added to vector, so advance the count

    // /node 0 is assigned, now generate the next N-1 values checking for duplicates
    while (NodeCnt < N) {
        x = dis(gen); //
        y = dis(gen); // generate a new random pt
        pt.Set(x, y);
        cout << "##############################" << endl;
        cout << "          New Points   " << endl;
        cout << "NodeCnt = " << NodeCnt << endl;
        cout << "pt = " << pt << endl;
        pti = NodeList[NodeCnt - 1];     //last pt added to NodeList
        cout << "pti = " << pti << endl;
        cout << "##############################" << endl;
        cout << endl;

        CheckCnt = 0;
        ptn = pti;

        //check new pt against previous pts in NodeList
        while (ptn != pt) {

                if((pti != pt) && (CheckCnt == NodeCnt)) {
                    // pixel is unique, Now put it on the NodeList
                    *p = pt;       // put pt in NodeList
                    ++p;           // advance ptr to next NodeList location
                    pti = NodeList[NodeCnt]; // now (pti == pt)
                    cout << "+++++++++++++++++++++++++++++" << endl;
                    cout << "NodeList[" << NodeCnt << "] = " << pti << endl;
                    cout << "NodeCnt = " << NodeCnt << endl;
                    cout << "CheckCnt = " << CheckCnt << endl;
                    ++NodeCnt;     // Node has been added, so advance the count
                    cout << endl;
                    cout << "New NodeCnt = " << NodeCnt << endl;
                    cout << "pt = "<<pt<<" = pti = "<<pti<<endl;
                    cout << "+++++++++++++++++++++++++++++" << endl;
                    cout << endl;
                    ptn = pt;
                }
                else if((pti != pt) && (CheckCnt <= (NodeCnt))) {
                    pti = NodeList[CheckCnt]; //  pti gets the next pt in NodeList
                    cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
                    cout << "CheckCnt = " << CheckCnt << endl;
                    cout << "NodeCnt = " << NodeCnt << endl;
                    cout << "pti = " << pti << endl;
                    cout << "pt = " << pt << endl;
                    ++CheckCnt;
                    cout << "CheckCnt = " << CheckCnt << endl;
                    pti = NodeList[CheckCnt]; //  pti gets the next pt in NodeList
                    cout << "pti = " << pti << endl;
                    cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
                    cout << endl;
                }
                else if ( (pti == pt) && (NodeCnt < CheckCnt) ) {
                    cout << "Duplicate node Found " << endl;
                    pti = pt;
                }
        } //inner while

        cout << "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" << endl;
        cout << "pti = " << pti << endl;
        cout << "pt = " << pt << endl;
        cout << "CheckCnt = " << CheckCnt << endl;
        cout << "NodeCnt = " << NodeCnt << endl;
        cout << "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" << endl;

    } outer while

    return 0;
}

Aucun commentaire:

Enregistrer un commentaire