I'm using the debugger to check if my programm works but I'm getting a segfault on a precise line. when I'm checking what's wrong, a local variable says <no such value>. What's happening? I've checked its value for each k and it's working until k=36. Do you think that local variables are reseted if I'm using it in a too long loop? I remember that I've used it in a loop where k=41 and it was working very well.
Variables of my class:
masseVolumique= 7850;
dExterieur= 0.1778;
epaisseur= 0.019;
masseFlotteur1 = 526;
masseFlotteur2 = 94;
largeurFlotteur1 = 1.35+2;
largeurFlotteur2 = 0.83+2;
rayonBends = 0.699;
precision = 2;
All the other variables are defined and I can see their value in the debugger mode.
int k=0;
j=0;
double theta=0;
double phi=0;
double offsetDebut;
double offsetFin;
double r=0;
int nbPos = 0;
for(int i=0;i<nbSegments;i++)
{
theta=acos((coordonnees[i+1][0]-coordonnees[i][0])/pow(pow(coordonnees[i+1][0]-coordonnees[i][0],2)+pow(coordonnees[i+1][1]-coordonnees[i][1],2),0.5));
phi=acos((coordonnees[i+1][2]-coordonnees[i][2])/pow(pow(coordonnees[i+1][0]-coordonnees[i][0],2)+pow(coordonnees[i+1][1]-coordonnees[i][1],2)+pow(coordonnees[i+1][2]-coordonnees[i][2],2),0.5));
if(i==0)
{
offsetDebut=3+largeurFlotteur1/2;
}
else
{
offsetDebut=rayonBends+largeurFlotteur1/2;
}
if(i==(nbSegments-1))
{
offsetFin=3+largeurFlotteur1/2;
}
else
{
offsetFin=rayonBends+largeurFlotteur1/2;
}
j=0;
do
{
r=j*precision+offsetDebut; //segfault: precision <no such value>
tabPos[k*5+0]=k;
tabPos[k*5+1]=i+1;
tabPos[k*5+2]=coordonnees[i][0]+r*cos(theta)*sin(phi);
tabPos[k*5+3]=coordonnees[i][1]+r*sin(theta)*sin(phi);
if(r*cos(phi)<0.01)
{
tabPos[k*5+4]=coordonnees[i][2];
}
else
{
tabPos[k*5+4]=coordonnees[i][2]+r*cos(phi);
}
k=k+1;
j=j+1;
}
while (r<(segments[i]-offsetFin)) ;
}
Ok the problem came from the calculation of tabPos length. I was calculating a too short length. In the loop, I was trying to access part of tabPos that were not declared.
Actually, I think a lot of segfault problem comes from index problems. I'll look at this very carefully now.
Related
I recently made a function to compare an array of numbers to a single value which returns the closest value to the single value out of the array. This works perfectly well when you only use it only once but if I use it again in another instance of the code, It returns an unexpected value (usually the previous single value used before). Here is the function that I am using:
double closestval (double num1, int amountofnums, double *comps){
double storagecomps[amountofnums];
for (int i = 0; i < amountofnums; i++){
storagecomps[i] = {comps[i]};
/* Storing the array of numbers for later as I will be changing them */
}
double smallval = 0.0001; /* tiny value used to increment/decrement
values in the array to the comparison variable.*/
int_fast64_t compi [amountofnums]; /* this variable keeps track of how many times it needs to decrement/increment the values in the array to approach the variable*/
for (int i = 0; i < amountofnums; i++){
compi[i] = 0;
}
for (int i = 0; i <= amountofnums; i++){
while (comps[i] > num1){
comps[i] -= smallval;
compi[i]++;
}
while (comps[i] < num1){
comps[i] += smallval;
compi[i]++;
}
double recholder[3] = {10000000, 0,};
// This area finds the
for (int i = 0; i < amountofnums; i++){
if (compi[i] < recholder[0]){
recholder[0] = compi[i];
recholder [1] = i;
recholder[2] = storagecomps[i]; /* if the amount of iterations to approach the single variable is less than the previous record holder, it becomes the new one.
*/
}
}
return recholder[2];
}
I am relatively sure this is because (in one way or another) the variables in the function are not being redefined properly or at all. Much thanks if you can show me where I've gone wrong!
The problem isn't resetting the variables. The problem is that you are modifying the arguments passed to the function.
To prevent modifications you should use the const keyword:
double closestval (double num1, int amountofnums, const double *comps){
and then fix the errors the compilers throws at you.
If you do want to modify the comps inside the functions but not have it affect the values outside the functions then you should usestd::vector so you can pass them by value and the compiler will copy them:
double closestval (double num1, int amountofnums, std::vector<double> comps){
You should really do that anyway as you should forget all about C-style arrays till you are an expert.
I'm having trouble understanding why my return data is garbage when I don't use debug to print it out and is fine when I do print it out. I am using C++ make_tuple and tie on the other end for float values. If I don't include enough info let me know!
I have tried checking for uninitialized data by printing out my functions. I also use this exact same code in other parts of the program with no issue.
To give a background of what this program is. I am reading an adc value getting the max value (with error checking) and then sending it for a pass-fail for the system and display to the user. I can work around this in a few ways but I am mostly just curious about this bug.
std::tuple<float,float> hardware_control::hv_check()
{
float hv_filtered_max = 0;
float hv_filtered_avg = 0;
int samples = HV_SAMPLES;
float hv_adc_read[samples];
int non_zero_samples = 0;
int i = 0;
int loops = 0;
//here we will take the a number of samples, average and find the max
while((i < samples) && (hv_filtered_max < HV_Voltage_MAX_CHECK)) // check if less than HV_MIN to speed up test (basically stop testing if it has passed the check)
{
hv_adc_read[i] = check_adc(7);
if(hv_adc_read[i] > 0 && hv_adc_read[i] < 10)
{
hv_filtered_avg += hv_adc_read[i];
non_zero_samples++;
i++;
}
if((hv_adc_read[i] > hv_filtered_max) && hv_adc_read[i] < 10)
{
hv_filtered_max = hv_adc_read[i];
}
loops++;
if(loops > 500) // stop sampling at 500 if we never get anything (this is protection for it possibly freezing i we sample nothing)
{
hv_filtered_max = 0;
break;
}
}
hv_filtered_avg = hv_filtered_avg/non_zero_samples;
return std::make_tuple(hv_filtered_avg,hv_filtered_max);
}
hardware_control hwc;
//where I call and return the data
std::tie(Ins_Data.hv_avg,Ins_Data.hv_max) = hwc.hv_check();
//Me printing out the values
qDebug()<<"MAX_OUTSIDE"<<Ins_Data.hv_max<<endl;
Ins_Data.hv_errors = hwc.HV_error_check();
log_data.push_back("HV_AVG");
log_data.push_back(QString::number(Ins_Data.hv_avg*3));
log_data.push_back("HV_MAX");
log_data.push_back(QString::number(Ins_Data.hv_max*3));
Why this annoys me so bad is that every time I print it out with the qDebug() function it works! if I comment it out, it goes back to 3.8581*10^-38
The value magically comes back to the correct value.
What's going on here? My guess is the make_tuple and tie is corrupting the memory but if so then why is it only sporadically doing it? and why only one of the floats?
SOLVED
I was sampling beyond my initialized array. My array is set to "HV_SAMPLES" however the max number of loops was 500, therefore it sampled beyond the size of my array. Debug functionality must have added some cushion between the array and other values allowing it to output correctly.
Here is the chunk of code in question that I've pulled from my program:
#include <vector>
using namespace std;
vector<double> permittingConstructionCosts(56);
static const int PERMITTING_PERIODS = 0;
static const int CONSTRUCTION_PERIODS = 11;
static const double CONSTRUCTION_COSTS = 2169506;
static const double PERMITTING_COSTS = 142085;
static const int PERMITTING_CONSTRUCTION_PERIODS = PERMITTING_PERIODS + CONSTRUCTION_PERIODS;
void calcExpenses // Calculates permitting and construction expenses
(
vector<double>& expense,
double value1,
double value2
)
{
int i;
for (i=0; i<=PERMITTING_PERIODS + 1; i++)
{
expense[i] = value1;
}
for (i=PERMITTING_PERIODS + 2; i<expense.size(); i++)
{
if (i < PERMITTING_CONSTRUCTION_PERIODS + 2)
{
expense[i] = value2;
}
}
}
int main()
{
if (PERMITTING_PERIODS != 0)
{
calcExpenses(permittingConstructionCosts, -PERMITTING_COSTS/PERMITTING_PERIODS, -CONSTRUCTION_COSTS/CONSTRUCTION_PERIODS);
}
else
{
calcExpenses(permittingConstructionCosts, 0, -CONSTRUCTION_COSTS/CONSTRUCTION_PERIODS);
}
return 0;
}
According to ideone (http://ideone.com/LpzUny) the code has a runtime error that returns "time: 0 memory: 3456 signal:11".
I've tried to look for solutions on SO and found the following links:
How can I avoid a warning about division-by-zero in this template code?
How to eliminate "divide by 0" error in template code
However, I don't know how to use templates because I am new to c++ and I'm not sure I need to use them in this case so I have no clue how to adapt those solutions to my particular problem if it's even possible.
I'm pretty sure that the "-PERMITTING_COSTS/PERMITTING_PERIODS" is causing the problem but I thought that simply checking the divisor would solve the problem. This function seems to work for every other value other than 0 but I need to account for the case where PERMITTING_PERIODS = 0 somehow.
I would very much appreciate any help I can get. Thanks in advance!
Edit: I actually do initialize the vector in my program but I forgot to put that in because the size is decided elsewhere in the program. The chunk of code works once I fix that part by putting in a number but my program still has a runtime error when I set PERMITTING_PERIODS to 0 so I guess I have to go bug hunting elsewhere. Thanks for the help!
The problem lies inside the function, which is called by the else statement in the main function:
for (i=0; i<=PERMITTING_PERIODS + 1; i++)
{
expense[i] = value1;
}
Here, PERMITTING_PERIODS is 0, thus you loop from 0 to 2 (inclusive).
However, expense.size() is 0, since your vector is empty. As a result, you are trying to access an empty vector, which causes a segmentation fault.
With that said, print the value of i inside the loop, you should see that you try to access expense[0], but the vector is empty, so it has no first slot (basically it doesn't have any)!!
So replace that with:
expense.push_back(value1);
which will allocate enough space for your values to be pushed into the vector.
The answer given in the cited links, (i.e. "How to eliminate "divide by 0" error in template code") applies equally well here. The other answers were given in the context of templates, but this is completely irrelevant. The sample principle applies equally well with non-template code, too. The key principle is to compute a division, but if the denominator is zero, you want to compute the value of zero instead of the division.
So we want to compute -PERMITTING_COSTS/PERMITTING_PERIODS, but use the value of 0 instead of the division when PERMITTING_PERIODS is 0. Fine:
int main()
{
calcExpenses(permittingConstructionCosts,
(PERMITTING_PERIODS == 0 ? 0: -PERMITTING_COSTS)/
(PERMITTING_PERIODS == 0 ? 1: PERMITTING_PERIODS),
-CONSTRUCTION_COSTS/CONSTRUCTION_PERIODS);
return 0;
}
Can some one tell me what is wrong in the for loop? When I run it, it interrupts. I tried to debug to see what is wrong, I noticed that in the for loop it just stops:
#define MAX_POPULATION 64
float **tr_pop;//Tournament candidates
float **matingPool;//Mating pool
tr_pop=new float *[m];
matingPool=new float *[m];
for(l=0;l<m+1;l++)//allocating
{
tr_pop[l]=new float[MAX_POPULATION];
matingPool[l]=new float[MAX_POPULATION];
}
for ( int r = 0; r < row; ++r )//deleting
{
delete [] matingPool[r];//Stops here (not ending program just frozen)
delete [] tr_pop[r];
}
delete [] tr_pop;
delete [] matingPool;
=======OK. PROBLEM SOLVED=======
Here is the reason:
I just changed the MAX_POPULATION into the MAX_POPULATION+1 and it worked.
for(l=0;l<m+1;l++)
{
tr_pop[l]=new float[MAX_POPULATION+1];
matingPool[l]=new float[MAX_POPULATION+1];
}
Because in another function I think I was doing violation:
void crossover()
{
int p1,p2,i,j;float tempBit;
p1=m/3;
p2=(2*m)/3;
for(j=0;j<MAX_POPULATION;j++)
{
for(i=p1;i<p2;i++)
{
tempBit=matingPool[i][j];
matingPool[i][j]=matingPool[i][j+1];//THE VIOLATION POINT (I THINK)
matingPool[i][j+1]=tempBit;
}
j++;
}
As you can see, when j = MAX_POPULATION at the end of the loop, i was trying to reach MAX_POPULATION + 1. So I changed the allocations for columns, and the problem solved :)
You're running into undefined behavior:
for(l=0;l<m+1;l++)//allocating
{
tr_pop[l]=new float[MAX_POPULATION];
}
should be
for(l=0;l<m;l++)//allocating
{
tr_pop[l]=new float[MAX_POPULATION];
}
You're allocating m elements for each of the arrays and try to access m+1.
You are allocating m float* but in for loop you are iterating from 0..m while allocating memory, it should from 0..m-1. For that you need to chnage the for loop to : for(l=0;l<m;l++).
I'm working in a real time ploting appication with MSChart...I need to set some y values to NaN but I'm getting an overflow exception. Here is the part of the code where it happen:
if (j_ecg < 2569)
{
for (int i = 0; i < 32; i++)
{
this.Invoke((MethodInvoker)delegate
{
ECG.Points.AddXY(puntos_ecg[j_ecg].X,puntos_ecg[j_ecg].Y);
});
j_ecg++;
}
}
else
{
for (int i = 0; i < 32; i++)
{
this.Invoke((MethodInvoker)delegate
{
ECG.Points[ecg_s].SetValueY(puntos_ecg[j_ecg].Y);
for (int j = 1; j < 10; j++){ ECG.Points[ecg_s + j].SetValueY(double.NaN); }
});
j_ecg++;
ecg_s++;
if (ecg_s == 2560) { ecg_s = 0; }
}
}
The Invokes are there to avoid cross threads issues.
Any idea of how can I do it for not getting the exception? I've try using unchecked keyword just before the SetValueY call but nothing changes.
First thing to try is disabling autoscaling so that min/max don't need to be calculated:
chart1.ChartAreas["Default"].AxisY.Minimum = <your min>;
chart1.ChartAreas["Default"].AxisY.Maximum = <your max>;
However you still need to have at least one real value in one of your series.
I recommend you keep track of your displayed values. If everything is NaN, stop plotting! When the next valid value comes in resume plotting.
Note: using zeroes instead of NaN is another solution.