0

I have the current class

class VectorVectorRow : public virtual RowFormat {

private:
    std::vector<std::vector<double>>* mat;
    int r_pos;

public:
    VectorVectorRow  (std::vector<std::vector<double>>* r,int pos) : mat{r}, r_pos{pos} {};
    VectorVectorRow (const VectorVectorRow& a) : mat(a.mat), r_pos{a.r_pos} {}

    //Where the SIGABRT exception is risen
    virtual ~VectorVectorRow()  = default; // inline;
    virtual double getCell(int pos);
    virtual int getSize();
    virtual void setCell(int pos, double value);
};

which inherits the following virtual class:

class RowFormat { public:

    RowFormat() {};
    /**
     * @param pos   returns the cell at the current position
     */
    virtual double getCell(int pos)  = 0;

    /** returns the size of the row
    */
    virtual int getSize()  = 0;

    /**
     * @param pos       position of the cell
     * @param value     value that has to be stored
     */
    virtual void setCell(int pos, double value)  = 0;

    void increment(int pos, double value) {
        setCell(pos,getCell(pos)+value);
    }

    virtual ~RowFormat() =default; };

An instance of the first class is used in the following way:

for(int epoch=0; epoch < training_epochs; epoch++) {
    for (int row=0; row < train_N; row++) {
        unique_ptr<RowFormat> k{std::move(df->getRow(row))}; //getRow returns an unique_ptr of VectorVectorRow up-casted to RowFormat
        da.train(k.get(),learning_rate,corruption_level);
        // just before the block close, a SIGABRT exception is risen
    }
}

Where getRow for the specific instance of df is defined as follows:

// std::shared_ptr<std::vector<std::vector<double>>> mat;
std::unique_ptr<RowFormat> VectorVectorData::getRow(int pos) {
    std::unique_ptr<VectorVectorRow> ptr{new VectorVectorRow(mat.get(),pos)};
    std::unique_ptr<RowFormat> casted{dynamic_cast<RowFormat*>(ptr.get())};
    return casted;
}

The complete stack call is the following one: stack call depiction

I even tried to replace the std::vector<std::vector<double>>* mat; with a std::shared_ptr, but the error still persists. How could I avoid the execption at the end of the block? Thanks in advance.

jackb
  • 695
  • 8
  • 26
  • 6
    This has all the signs of memory corruption and undefined behavior. The bug does not occur in the destructor, but at some earlier, unknown, point, that corrupts the heap or the stack where the vector resides, resulting in a runtime exception in the destructor. Use a debugger, and a static analysis tool, to identify and isolate your bug. Welcome to C++. – Sam Varshavchik Dec 15 '15 at 13:37
  • Please post a MCV example http://stackoverflow.com/help/mcve we need to know the `getRow` function – Danh Dec 15 '15 at 13:48
  • This seems like a double free corruption. Say like You freed a memory twice – Danh Dec 15 '15 at 13:50
  • @Danh, I just thought that the error didn't depend on that function. I've just edited the post. – jackb Dec 15 '15 at 13:56
  • Exactly, you have freed it twice, one by the `unique_ptr` in the `getRow` once in for loop. Replace the cal to `std::unique_ptr::get` with `std::unique_ptr::release` by the way, I recommend `std::make_unique` instead of calling `new` inside a constructor – Danh Dec 15 '15 at 14:04
  • Is there any specific reason to use virtual inheritance here? In this case normal inheritance would suffice. – Ilya Popov Dec 16 '15 at 00:17
  • Yep, in this case there are different definitions of RowFormat's subclasses for different specific data types. It is like a Java interface, where all the methods are implemented differently in all the subclasses. – jackb Dec 16 '15 at 00:18

0 Answers0