SIGSEGV through writing to local variable - c++

I'm currently encountering the most strange behavior in my C++ project. What I'm trying to do is calculate the euclidean distance between two double vectors (well, actually, vectors of double vectors, hence the m_Data[0].size()).
This is the source:
double NEAT::Behavior::Distance_To(NEAT::PhenotypeBehavior* other)
{
double sum = 0.0;
for (int i = 0; i < m_Data[0].size() && i < other->m_Data[0].size(); i++) {
double x1 = m_Data[0][i];
double x2 = b->m_Data[0][i];
double difference = x1 - x2;
difference *= difference;
sum += difference;
}
return sqrt(sum);
}
I initially had all this written in one line, but I've split it up to locate the error. What happens is that after a few thousand calls to this function, it throws a SIGSEGV at the last line of the for loop:
sum += difference;
I have NO idea how this could happen. I've checked the stack trace, it's from the Distance_To(...) function and it gets thrown at this line precisely. As soon as I comment it out, everything's fine (but of course the function won't work lol). The signal gets thrown at the same time each time I run the program with the same objects interacting.
Help would be much appreciated. Thanks!
Edit: I've verified the integrity of the pointers in this method by printing out the needed values before entering the loop. All values get printed correctly. Here is the complete version of the function I used for debugging purposes:
double NEAT::Behavior::Distance_To(NEAT::PhenotypeBehavior* other)
{
double sum = 0.0;
Behavior* b = (Behavior*) other;
// Gets executed without any problems
if (genomeid == 300 && b->genomeid == 399) {
std::cout << "PROBLEM CASE" << std::endl;
std::cout << "Printing values for 300..." << std::endl;
for (int i = 0; i < m_Data[0].size(); i++) std::cout << m_Data[0][i] << std::endl;
std::cout << "Printing values for 399..." << std::endl;
for (int i = 0; i < m_Data[0].size(); i++) std::cout << b->m_Data[0][i] << std::endl;
}
// Doesn't get executed
if (m_Data[0].size() != other->m_Data[0].size()) {
std::cout << "Different sizes, " << m_Data[0].size() << " and " << b->m_Data[0].size() << std::endl;
}
// SIGSEGV at size() call
for (int i = 0; i < m_Data[0].size() && i < b->m_Data[0].size(); i++) {
double x1 = m_Data[0][i];
double x2 = b->m_Data[0][i];
double difference = x1 - x2;
difference *= difference;
// If this line gets commented out, no SIGSEGV but the program starts behaving weirdly afterwards (suddenly different sizes after the faulty run)
sum += difference;
}
return sqrt(sum);
}

ASAN and valgrind are the tools you should use to identify the root cause of this type of errors. Eventhough the error thrown at line sum += difference, your actual error could be somewhere else before hitting this point which corrupts your memory. These tools will help you to track that.

Sorry guys, I missed out on some MultiNEAT framework functions I should've used but didn't for initializing the objects etc. Anyways, thanks a lot to all of you, I learned a lot about using valgrind and ASAN (both are really handy and I didn't know about either of them before! lol) and even got a few good articles to read. Duh!

Related

Release vs Debug version: suddenly runtime error

I have a program that performs an FFT on a 2d array. In order to work with the fft library fftw3 I have to use a temporary array (called FTtemp) that reads out the result of the FFT: it is 3d since it contains the x & y axis plus the real and imaginary value for each (x,y) tupel.
The transfer of the data from the FFT array (which has a special variable type) to the ordinary array is working in debug mode but not in release. In release I get the following runtime error: Access violation writing location 0x02913000.
From my google search I found that release version bugs are usually related to uninitialized objects. This led me to explicitly initialise every item in FTtemp with 0.0, however to no avail. Furthermore, I printed the FFt array items to console and numbers appeared which means that they are also initialised. Hence, I am a bit out of ideas and wondered if someone might be wiser than me?
Here is the code snippet I am talking about. Since the program relies on a lot of other things, I was not quite able to recreate a minimal example yet, but I will add one as soon as I got the same error.
Fun fact: I print the I & j values of the loop to the console for trouble shooting and it is another (I,j) tupel where it crashes every time when I run it: eg: 49,212 or 116,169. I am really confused by this.
FTtemp = new double** [width];
for (i = 0; i < width; i++) {
FTtemp[i] = new double*[height];
}
for ( i = 0; i < width; i++)
{
for (j = 0; j < height; j++) {
FTtemp[i][j] = new double[2];
FTtemp[i][j][0] = 0.0;
FTtemp[i][j][1] = 0.0;
}
}
cout << "width,height: " << width << "," << height << endl;
for (i = 0; i < width; i++)
{
for (j = 0; j < height; j++) {
/*
cout << "access to out: " << out[indexFFT(i, j)][0] << endl;
cout << "access to FTtemp: " << FTtemp[i][j][1] << endl;
*/
cout << "i,j is: " << i << "," << j << endl;
FTtemp[i][j][1] = out[indexFFT(i, j)][0]; <--------- error occours here
FTtemp[i][j][2] = out[indexFFT(i, j)][1];
}
}
Thank you for your consideration.
All the best,
Blue
There is an error in this line:
FTtemp[i][j][2] = out[indexFFT(i, j)][1];
Notice that FTtemp[i][j] is initialized to new double[2] earlier in your code, which means that FTtemp[i][j][2] is an out-of-bounds write.
There may be other issues here - perhaps indexFFT(i, j) gives a bad index? - but without seeing how out was initialized or how indexFFT works we can't be sure.
Hope this helps!

Double vector hides variables

I'm having an interesting problem when I'm accessing a double vector. The idea is that I have deleted all information prior to accessing the vector. A for loop tries to access the vector and successful says that the vector is empty, but when I access the vector point directly it shows that there are variables still in the vector.
Also, the vector was set up like so:
vector<vector<string>> proTable;
Here is the loop attempting to access the vector.
for(int a = 0; a < proTable.size(); a++)
{
for(int b = 0; b < proTable[a].size(); b++)
{
cout << proTable[a][b] << "\t";
}
}
But if I edit the for loop this way it returns the variable inside.
for(int a = 0; a < proTable.size(); a++)
{
for(int b = 0; b < proTable[a].size(); b++)
{
cout << proTable[a][b] << "\t";
}
cout << proTable[0][0];
}
The first prints nothing out. The second prints X which was in the vector before. Also, the vector does not show that it is empty.
This is how I was deleting it if it matters.
void MRelation::RemoveColumn(vector<int> rem)
{
while(!rem.empty())
{
int z = rem[rem.size() - 1];
for(int a = 0; a < proTable.size(); a++)
{
for(int b = z; b < proTable[a].size() - 1; b++)
{
proTable[a][b] = proTable[a][b+1];
}
proTable[a].pop_back();
}
rem.pop_back();
}
}
The vector rem holds the columns that need to be deleted from the table.
I have deleted all information prior to accessing the vector.
Accessing an vector out of bounds has undefined behaviour. Since your vector is empty, proTable[0] is out of bounds. In the line cout << proTable[0][0];, you access proTable[0]. Therefore the behaviour of your program is undefined.
it shows that there are variables still in the vector.
You cannot jump to such conclusion from observing undefined behaviour.
"There are variables still in the vector" was not necessarily the reason why you saw output. You saw output because the behaviour was undefined.
I found out what it was. I you delete the contents of the inner vector but don't delete the vectors themselves then the vector will think that it contains something still and will pull out information that doesn't exist anymore. here is the code I was have problems with. It has been edited with an if statement to correct it.
void MRelation::FinalPrint()
{
if(curTable.size() < 2)
{
ss << "? No\n";
}
else
{
ss << "? Yes(" << curTable.size() - 1 << ")\n";
}
if(!proTable[0].empty()) //This was added in after to correct the problem
{
for(int c = 1; c < proTable.size(); c++)
{
ss << " " << proTable[0][0] << "=" << proTable[c][0];
for(int d = 1; d < proTable[0].size(); d++)
{
ss << ", ";
ss << proTable[0][d] << "=" << proTable[c][d];
}
ss << "\n";
}
}
}
Sorry about not putting everything in context before. I was trying to put in as much relavant information without putting in 300 lines of code.

Reading into hashmap in c++

I'm working on a markov chain and have created a 2d hashmap that calculates the weighted probabilities. The output of this works fine.
I'm looking to find the best way to output the next value. The way I have it at the moment isn't working properly. Ent1.first is the incoming midiNote. Ent2.first is the potential outgoing value and Ent2.second is the weighted probability.
When midiNotecomes in, I need to look into the table and find the weighted probabilities and using rand() pick the next value. One problem is that I only need this to happen once, not for every time in the for loop. Here is a snippet of my table calculation for simplicity's sake, but if you'd like me to post the entire code let me know.
void getCountTable(int midiNote) {
for(auto const &ent1: cdf) {
midiNote = ent1.first;
for (auto const &ent2: ent1.second) {
//console out all resulting note transition weights
//std::cout << "Note: " << ent1.first << std::endl <<"Next note: " << ent2.first <<std::endl << "Weight: " << ent2.second << std::endl << std::endl;
//TRYING TO FIGURE HOW TO HANDLE THIS. JUST WANT TO HAPPEN ONCE FOR EACH INCOMING VALUE
//psuedo-random values between 0-1
float r = static_cast <float> (rand()) / static_cast<float> (RAND_MAX);
//calculate next value
if (r < ent2.second) {
int output = ent2.first;
std::cout << ent1.first << " " << output << std::endl;
}
}
}
}
Currently you are creating a new random number each time around your inner loop and comparing it with the chance for that possibility. This will mean that sometimes one item will match (good), but sometimes you will get zero or two or more items matching (it is random).
One way to pick the just one possibility out of all the options is to generate one random number, then loop through the possibilities until the sum of all the possibilities so far is greater than the random number that you have generated.
Rearranging your code (untested)
midiNote = ent1.first;
//psuedo-random values between 0-1
float r = static_cast <float> (rand()) / static_cast<float> (RAND_MAX);
float sum = 0;
int output = 0;
for (auto const &ent2: ent1.second){
sum += ent2.second;
if (sum >= r) {
output = ent2.first;
std::cout << ent1.first << " " << output << std::endl;
break;
}
}
This should work, although given the inexactness of floating point additions, it might be worth defaulting output to the last item of ent1.second if nothing is found (e.g. this might happen if sum ends up at 0.999, but r was 0.9999)
I've found there needs to be a comparison between the map and the incoming midi value. Also changed the probabilities to the first entry in the second map and the resulting output as the second entry. Modified some and provided all below.
void nextNote(int midiNote){
float r = static_cast <float> (rand()) / static_cast<float> (RAND_MAX);
int output = 0;
float sum = 0;
for (auto const & ent1: cdf){
if(ent1.first == midiNote){
for (auto const & ent2: ent1.second){
sum+= ent2.first;
std::cout <<sum << std::endl;
if(sum >= r){
output = ent2.second;
std::cout << output <<std::endl;
break;
}
}
}
}
}

Finding this strange bug? It crashes without noticing anything

I wrote a function within my code that should create some sort of matrices. It is fine when the size is small, but when it gets bigger, it crashes at the middle of this function without giving any information. I did that with both debug and release mode and same thing happened. Any idea on what can be wrong? Someone suggested me it could be buffer overrun.
In this function when kl.mechelms get bigger than a certain number, it crashes. The following code uses a function and gets a 3 by 3 matrix and stores it in kl.scoff which size is [3][3][kl.mechelms][kl.mechelms]. The problem happens when kl.mechelms are like bigger than 7000, but we need far more than that for our code.
Could the function Calc_3D which I use within this part cause the problem? I think it shouldn't since it just reads some values.
for (int z = 0;z<3;z++) {
for (int q = 0;q<3;q++) {
kl.scofsarr[z][q] = new double *[kl.mechelms];
}
}
for (int i = 0;i<kl.mechelms;i++) {
cout << "element " << i << "of " << kl.mechelms << endl;
kl.comments << "element " << i << "of " << kl.mechelms << endl;
for (int z = 0;z<3;z++) {
for (int q = 0;q<3;q++) {
kl.scofsarr[z][q][i] = new double[kl.mechelms];
}
}
for (int j = 0;j<kl.mechelms;j++) {
Calc_3D(i,j, kl.elmx[j], kl.elmy[j], kl.elmz[j], kl.anglemat[j], kl.dip[j], kl.elmx[i],kl.elmy[i],kl.elmz[i],
kl.elma[i],kl.rectza,kl.anglemat[i],kl.dip[i], kl.G, kl.v, kl.scofs, kl.rdepth);
for (int z = 0;z<3;z++) {
for (int q = 0;q<3;q++) {
kl.scofsarr[z][q][i][j] = kl.scofs[z][q];
}
}
}
}

Assertion failed in Mat OpenCV

I am running the EM algorithm in OpenCV several times in a loop. Initially the EM runs with default initial parameters. In subsequent iterations we pass parameters to the EM algorithm based on output of previous iteration. Here is the code
Mat meansCombine;
Mat weightsCombine;
vector<Mat> covsCombine;
for(int k=maxComponents; k>=minComponents; k--){
EM model(k,EM::COV_MAT_DIAGONAL,TermCriteria(TermCriteria::COUNT+TermCriteria::EPS,2,0.0001));
Mat labels;
Mat probs;
Mat log_likelihoods;
if( k==maxComponents )
{
model.train(samples,log_likelihoods, labels, probs);
}
else
{
model.trainE(samples, meansCombine, covsCombine, weightsCombine, log_likelihoods, labels, probs); //provide parameters as per previous iteration results
}
double total_likelihood = 0.0;
for(int i=0;i<log_likelihoods.rows;i++){
double t = log_likelihoods.at<double>(i,0);
total_likelihood += t;
}
int dimension =3;
double l = k*(1 + dimension + ((dimension+1)*dimension)/2)-1;
double penalty = 0.5*l*log(samples.rows*dimension);
double mdl = -total_likelihood + penalty;
mdl_output << "********** No. of components=" << k << "***********" << endl;
mdl_output << "Total log likelihood=" << total_likelihood << endl;
mdl_output << "Penalty=" << penalty << endl;
mdl_output << "MDL value=" << mdl << endl;
if(mdl < minMdl)
{
minMdl = mdl;
minK = k;
}
int c1,c2;
Mat means = model.get<Mat>("means");
Mat weights = model.get<Mat>("weights");
vector<Mat> covs = model.get<vector<Mat> >("covs");
leastBhattacharyaDist(means,covs,c1,c2);
mdl_output << "Merging components" << c1 <<" and " << c2 <<endl;
meansCombine = Mat(means.rows-1,means.cols,means.type());
weightsCombine = Mat(weights.rows,(weights.cols)-1,weights.type());
covsCombine.clear();
mergeComponents(means,covs,weights,c1,c2,meansCombine,covsCombine,weightsCombine);
}
Running this code gives me the following assertion failed message.
Assertion failed (0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows) in Mat, file /home/one_more_step/Documents/OpenCV/opencv-2.4.7/modules/core/src/matrix.cpp, line 284
Not able to trace the bug. Thanks in advance.
Asserts usually indicate that the following code was written with certain assumptions in mind - and your parameters do not fit the assumptions. (The dumbest thing you can do is remove the assert - yes, the code may work, but after all the assumptions aren't met so you'll shoot yourself in the foot somewhere in the future).
Asserts sometimes are complicated because they may be triggered by variables or code flows you do not control.
Usually an assertion is pretty easy to debug. Just run your code within the debugger, when the assertion happens: look at the backtrace.
The backtrace will tell you where the call happens from the code you show above.
By stepping along the frames of the backtrace, you can inspect the value of all variables along - which will tell you why the assert went off.