salomons
salomons

Reputation: 199

"incorrect checksum for freed object", but I didn't free it

Problem solved

Thanks all for your engagement in my error searching!

Thanks @Basile Starynkevitch for telling me about valgrind. Thanks @Anders K. for pointing out that it might have to do with the allocation/deallocation of x and w.

The problem was that the allocated memory for double x[] was too small, which lead to, which Anders pointed out, that I overwrote data in other places. This eventually lead to the crashes of my program.

Hans

..........................................................................................................................................

Sitting with my master thesis trying to implement a self organizing map (SOM) when I encountered the following error:

program(39652,0x7fff70055cc0) malloc: *** error for object 0x100555108:  
incorrect checksum for freed object - object was probably modified after being freed.

The thing is that I haven't deallocated any memory. The object that is causing the problem is a vector<Point> points object. The Point class has a member vector<PriceData> data. PriceData is a struct holding primitive values. Here is the stacktrace:

#0  0x00007fff803880b6 in __kill ()
#1  0x00007fff804289f6 in abort ()
#2  0x00007fff8041762d in szone_error ()
#3  0x00007fff8033e80b in tiny_malloc_from_free_list ()
#4  0x00007fff8033dabd in szone_malloc_should_clear ()
#5  0x00007fff8033d98a in malloc_zone_malloc ()
#6  0x00007fff8033bc88 in malloc ()
#7  0x00007fff88732f05 in operator new ()
#8  0x000000010001d3d1 in __gnu_cxx::new_allocator<PriceData>::allocate () at stl_construct.h:182
#9  0x000000010001d3f9 in std::_Vector_base<PriceData, std::allocator<PriceData> >::_M_allocate () at stl_construct.h:182
#10 0x000000010001d794 in std::_Vector_base<PriceData, std::allocator<PriceData> >::_Vector_base () at stl_construct.h:182
#11 0x000000010001d82f in std::vector<PriceData, std::allocator<PriceData> >::vector () at stl_construct.h:182
#12 0x000000010001d8c3 in Point::Point () at stl_construct.h:182
#13 0x000000010002193e in Som::startTraining () at stl_construct.h:182
#14 0x0000000100017465 in main () at main_controller.cpp:42

It goes wrong when I am trying to train my network. I pass a reference to the points object, which will not go out of scope here, right?

main_controller:

#include <iostream>
#include "stock_data_controller.h"
#include "pattern_controller.h"
#include "point.h"
#include "som.h"
#include <ctime>


using namespace std;

int main() {

    PatternController pc()

    // Train Kohonen network
    Som som(pc.points);
    som.startTraining(20000); // goes wrong in here!


    return 0;
}

Training works for approx 100 to 500 times (different every time) then I get the error. I have marked the place in the code wherefrom the error is thrown. Something has at this point gone bad with the points object.

Here is the data for som.cpp:

#include "som.h"
#include <cmath>
#include <cassert>

Som::Som(vector<Point> &pts, int gsize)  { //: points(pts) {

    // Initiera variabler
    points = pts;
    nrPoints = points.size();
    ptSize = points.at(1).data.size();
    gridSize = gsize;
    dimensions = 4*ptSize;

    initW();
    initX();
};

Som::~Som() {
    for (int i = 0; i < gridSize; i++) {
        for (int j = 0; j < gridSize; j++) {
            delete [] w[i][j];
        }
        delete [] w[i];
    }
    delete [] w;
};

void Som::startTraining(int nrIterations) {

    for(int i=0; i<nrIterations; i++) {
        // choose random pt

        // EROOR IS HERE // 
        Point pt = points.at(randomPointIndex()); // I have tried with constant 20 and got the same error.. 
            // ERROR IS HERE //


        buildX(pt);

        // Find winning neuron

        findWinningNeuron();

        // update weights
        cout << "Update weights" << endl;
        updateWeights(i);
        cout << "fUpdate weights" << endl;

        cout << "Iteration: " << i << endl;
    }

    cout << "Training of SOM is complete." << endl;
};

void Som::findWinningNeuron() {
    //init
    winner.distance = 1e6;

    for (int i=0; i<gridSize; i++) {
        for (int j=0; j<gridSize; j++) {
            double dist = computeEDistance(w[i][j]);
            if (dist<winner.distance) {
                winner.distance = dist;
                winner.row = i;
                winner.column = j;
            }
        }
    }
    assert( winner.distance != 1e6 );
};



void Som::updateWeights(int iterNr) {
    for (int i=0; i<gridSize; i++)
    {
        for (int j=0; j<gridSize; j++) {
            double eta = computeEta(iterNr);
            double h = computeH(iterNr, i, j);
            for (int k=0; k<dimensions; k++) {
                w[i][j][k] = w[i][j][k] + eta*h*(x[k]-w[i][j][k]);
            }
        }
    }
};

void Som::initW() {
    cout << "initW" << endl;
    srand(time(NULL));

    // Creating w
    cout << "creating w"<< endl;
    w = new double**[gridSize];
    for (int i = 0; i<gridSize; i++) {
        w[i] = new double*[gridSize];
        for (int j=0; j<gridSize; j++) {
            w[i][j] = new double[dimensions];
        }
    }
    // cout << "w size: " << sizeof( w[0][0] ) / sizeof( w[0][0][0] ) << endl;
    // Populating w
    cout << "populatiing w" << endl;
    for (int i = 0; i<gridSize; i++)
    {
        for (int j=0; j<gridSize; j++) {
            for (int k=0; k<dimensions; k++) {
                double r = double(rand()) / RAND_MAX * 0.4 +0.8;
                w[i][j][k] = r;
                            }
            }
        }       
    }

};

void Som::initX() {
    x= new double[ptSize];
};

void Som::buildX(Point &pt) {
    for (int i=0; i<ptSize; i++) {
        x[i*4] = pt.data.at(i).open;
        x[i*4+1] = pt.data.at(i).high;
        x[i*4+2] = pt.data.at(i).low;
        x[i*4+3] = pt.data.at(i).close;
    }
};

int Som::randomPointIndex() {
    // random point
    int r = rand() % nrPoints;
    cout << "r: " << r << endl;
    return r;
};

som.h:

#include <iostream>
#include <vector>
#include "point.h"
#include "models.h"

class Som {
private:
public:
    // Members
    double ***w;
    double *x;
    vector<Point> points;
    ...
    winner_t winner;

}   

Grateful for any help or pointers!! Thanks, Hans

Upvotes: 3

Views: 6039

Answers (1)

Consider using a tool like valgrind

Upvotes: 4

Related Questions