0

I'm working on a project and I'm trying to push back objects to an STL vector. The class is constructed the following way in the .hpp file:

class EDITOR{
    public:
    int DIMENSION; //the dimension is the same in case of every editor
    float* DIM_VALUES; //in every discipline of human knowledge every editor has values
    float ALPHA_E; // The probability that an editor knows a given discipline
    float activity; //parameter to describe different activeness of editors;

    /*Constructor of object EDITOR*/
    EDITOR(int dim = 20, float aE = 3);
    ~EDITOR();
};

and the .cpp file is the following:

EDITOR::EDITOR(int dim, float aE)
{
    std::cout<<"Constructor called\n";
    std::cout<<"DIM_VALUES pointer: "<<DIM_VALUES<<"\n";
    DIMENSION = dim;
    DIM_VALUES = new float[DIMENSION];
    ALPHA_E = aE;
    activity = (float) rand() / RAND_MAX;
    std::cout<<"DIM_VALUES pointer: "<<DIM_VALUES<<"\n";

    // Calculating the power law distribution discrete pk-s
    // Every editor must know at least 1 discipline
    float p0 = 0;

    // DISCRETE PROBABILITIES FOR n INTEGER NUMBERS FROM 1-DIMENSION
    // k max = DIMENSION, ez alapján a normálási tényező
    float norm = 0;
    for (auto i = 1; i <= DIMENSION; ++i)
        norm += (float)pow(i, -ALPHA_E);
    
    std::vector<float> pks;
    for (auto k = 1; k <= DIMENSION; ++k)
    {
        float pk = (float)pow(k, -ALPHA_E) / norm;
        pks.push_back(pk);
    }

    // determine how many disciplines does each editor know
    float f = (float)rand() / RAND_MAX;
    float base = 0;
    int m = 1; // number of disciplines known by each editor
    for (auto i = 0; i < DIMENSION; ++i)
    {
        if (base <= f && f <= base + pks.at(i))
        {
            m = i + 1;
            base += pks.at(i);
        }
        else
        {
            base += pks[i];
        }
    }

    // select m random disciplines from the DIMENSION disciplines
    std::vector<int> chosen_ones;
    while (chosen_ones.size() != m)
    {
        int pot_new = rand() % DIMENSION;
        bool is_ok = true;
        for (auto i = 0; i < chosen_ones.size(); ++i)
        {
            if (chosen_ones.at(i) == pot_new)
                is_ok = false;
        }
        if (is_ok)
            chosen_ones.push_back(pot_new);
    }

    std::sort(chosen_ones.begin(), chosen_ones.end());

    // fill up the random disciplines
    int j = 0;
    for (auto i = 0; i < DIMENSION; ++i)
    {
        if (i == chosen_ones[j])
        {
            this->DIM_VALUES[i] = (float)rand() / RAND_MAX;
            if (j < m)
                j += 1;
        }

        else
            DIM_VALUES[i] = 0;
    }

    // Hopefully finished;
    chosen_ones.clear();
    chosen_ones.shrink_to_fit();

    pks.clear();
    pks.shrink_to_fit();
}

EDITOR::~EDITOR(){
    std::cout<<"destructor called\n";
    delete[] DIM_VALUES;
}

The main function:

int main(){
    srand(1);

    std::vector<EDITOR> editors;
    for (auto i = 0; i < 100; ++i)
    {
        std::cout<<"i: "<<i<<std::endl;
        EDITOR new_ed;
        editors.push_back(new_ed);      
    }
}

Can you help me what causes the problem? I've found out that my loop stops after a destructor call, but I couldn't figure out anymore. Is there a memory issue? Or the destructor is not constructed well? Thank you for your help, I appreciate it a lot!

R_Magyar
  • 1
  • 1
  • 1
    Learn about the "rule of 3" (aka rule of 5, or rule of zero). Or just use `std::vector` instead of that raw dynamic allocation and live a happier life. – Mat May 03 '22 at 14:03
  • @R_Magyar In this statement std::cout<<"DIM_VALUES pointer: "< – Vlad from Moscow May 03 '22 at 14:11
  • You need to either implement or explicitly delete the copy and assignment operators. If you delete them you'll need to implement the move constructor instead and change `editors.push_back(new_ed)` to `editors.push_back(std::move(new_ed))` – Alan Birtles May 03 '22 at 14:12
  • Bypassing the copy issue with EDITOR you still have an out of bounds access here `if (i == chosen_ones.at(j))` I modified all the vector access to use `at()` instead of `[]`. https://godbolt.org/z/x6jYG74r8 The `clear()` and `shrink_to_fit()` calls at the end of the function are unnecessary as those local variables will be destroyed at the end of the function. – Retired Ninja May 03 '22 at 14:19

0 Answers0