Reputation: 199
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