No idea where seg fault is occuring [closed] - c++

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
For some reason, when I run this code, I get a seg fault when the value of i in the for-loop is 7654319. However the strange thing is that when I am not checking if the value is pan-digital, it works normally without a segfault. It also works when I am checking if it is just pandigital; but not for both. I used gdb to step through the code and here is the output I get:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004007d3 in main () at Pand.cc:81
81 if (isPandigital(i) && Primes[i])
6: Primes[i] = <error: Cannot access memory at address 0x7ffefffffff4>
5: i = <error: Cannot access memory at address 0x7ffefffffff4>
4: Primes[7654317] = <error: Cannot access memory at address 0x7ffefffffff8>
3: Primes[7654321] = <error: Cannot access memory at address 0x7ffefffffff8>
2: Primes[7654319] = <error: Cannot access memory at address 0x7ffefffffff8>
1: Primes = <error: Cannot access memory at address 0x7ffefffffff8>
From the output, it seems that by manipulating the value of i in the isPandigital(int) function, this also affects value of i in main. This didn't make any sense to me, but I went ahead and used a different variable to represent i in the isPandigital(int) function, but I still get the same error.
Can someone help me please? These kind of errors are so annoying because everything seems like it should be working, but it's not and the solution is just hiding itself under layers of implementation. Any help is appreciated!
#include <cstdio>
#define MAX 7700000
typedef unsigned int uint;
bool* GetPrimes()
{
const int Need = MAX;
bool* Sieve = new bool[Need];
for (int s = 0; s < Need; ++s)
Sieve[s] = 1;
bool Done = false;
uint w = 3;
while (!Done)
{
for (uint q = 3, Prod = w * q; Prod < (uint)Need ; q += 2, Prod = w * q)
Sieve[Prod] = false;
Done = (w > (Need >> 1) ? true : false);
w+=2;
}
return Sieve;
}
bool isPandigital(int num)
{
int arr [] = {1,2,3,4,5,6,7}, G, count = 7;
do
{
G = num%10;
if (arr[G-1])
--count;
arr[G-1] = 0;
} while (num/=10);
return (!count);
}
int main()
{
bool* Prime = GetPrimes();
int i;
for (i = 7654321 ;i > 2; i-=2)
{
if (Prime[i] && isPandigital(i))
break;
}
printf("%d\n", i);
return 0;
}

In your isPandigital function. Notice that if num is a multiple of ten or congruent to 8 or 9 mod 10, you'll have a few problems. Out-of-bounds array accesses often lead to segfaults.
The first prime for which this occurs is 19 (or 7654319 if you go backwards from 7654321):
bool isPandigital(int num)//num is (76543)19
{
int arr [] = {1,2,3,4,5,6,7}, G, count = 7;
do
{
G = num%10; //G is 9
if (arr[G-1]) //G-1 is 8; G is only indexed from 0 to 6.
--count;
arr[G-1] = 0; //G-1 is 8; G is only indexed from 0 to 6.
} while (num/=10);
return (!count);
}
Note that though the solution will not have an 8 or 9 in it, any prime you test might.

Look at:
G = num%10;
if (arr[G-1])
So, what if G is zero? This would also trash your stack, making debug hard.
On the face of it, isPandigital works nicely in the case when the number passed is pan-digital, else has an array bound under/overrun?

Related

Overlapping multidimensional array corruption [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a very insidious issue with two dynamically allocated and reallocated multidimensional arrays, defined as follows:
int *pRawVals[20][181];
and
int *pMaxPlaneRawPlanes[20][46];
These are allocated in a single function: (code condensed for clarity)
...
// iNlat and iNVer bounds checked and OK
for (int lat = 0; lat < iNlat; lat++)
{
pData->pBlendedRawPlanes[lat] = new long long[1 * (iNver + 1)];
for (int sensor = 0; sensor < 20; sensor++)
{
pData->pRawVals[sensor][lat] = new int[1 * (iNver + 1)];
for (int vert = 0; vert <= iNver; vert++)
{
pData->pRawVals[sensor][lat][vert] = SENSOR_UNREAD;
} // end for
} // end for
} // end for
...
for (int sensor = 0; sensor < 20; sensor++)
{
delete[] pData->strayVals[sensor];
pData->strayVals[sensor] = new int[1 * (iNver + 1)];
for (int vert = 0; vert < iNver + 1; vert++)
{
pData->strayVals[sensor][vert] = SENSOR_UNREAD;
} // end for
for (int lat = 0; lat < 46; lat++)
{
pData->pMaxPlaneRawPlanes[sensor][lat] = new int[361];
// for (int iFillMem = 0; iFillMem < 361; iFillMem++)
for (int vert = 0; vert < iNver; vert++)
{
pData->pMaxPlaneRawPlanes[sensor][lat][vert] = SENSOR_UNREAD;
} // end for
} // end for
} // end for
... and deallocated in another function:
for (int lat = 0; lat < pData->iNUserLats; lat++) // iNUserLats <= 181
{
for (int sensor = 0; sensor < 20; sensor++)
{
if (pData->pRawVals[sensor][lat] != NULL)
{
delete[] pData->pRawVals[sensor][lat];
pData->pRawVals[sensor][lat] = NULL;
} // end if
} // end for
}
...
for (int sensor = 0; sensor < 20; sensor++)
{
for (int lat = 0; lat < 46; lat++)
{
if (pData->pMaxPlaneRawPlanes[sensor][lat] != NULL)
{
delete[] pData->pMaxPlaneRawPlanes[sensor][lat];
pData->pMaxPlaneRawPlanes[sensor][lat] = NULL;
} // end if
} // end for
} // end for
Hope I got enough of the code posted. At any rate, when deallocating pMaxPlaneRawPlanes on a second pass through the code, it turns out that certain elements of that array overlap elements of pRawVals and the deallocation causes a crash - appears that those locations may have been freed previously but I can't seem to point the finger at exactly how it's happening.
Any hints on how to narrow that kind of thing down? I run development on Windows 7 Ultimate 64 bit, but the app is compiled for 32 bit.
Thanks
You may go out of range in any of your array, or you may go out of range elsewhere.
If you are using Visual Studio 2019, or you are using gcc or clang, you can give ASan (Address Sanitizer) a try. (VS2019 link)
Otherwise you can try Application Verifier with Full Heap check enabled.
It is also possible to use custom allocation and allocate memory the way that it will access violation on out of bounds, even if off by one. It is essentially duplicating Application Verifier for particular allocations.
Using std::array or std::vector recommended in comments will also help making fewer errors that lead to heap corruption in the first place. vector manages deallocations automatically, and also in debug builds may have checks for out-of-range errors.

C++ Segmentation fault: 11

I am getting Segmentation fault: 11 error when trying to run my program (I'm quite a n00b with c++ so take it easy on me). I know it has something to do with memory allocation but I'm not sure what exactly I am doing wrong. Can anyone please help and spot the problem/s?
Basically I'm trying to chop one vector into many small vectors, and analyse each one separately.
std::vector<double> test::getExactHit(std::vector<double> &hitBuffer, double threshold){
int resolution = 100;
int highestRMSBin = 0;
std::vector<double> exactHit(8192);
double* rmsInEachBin = new double[hitBuffer.size()/resolution];
double highestRMSValue = threshold;
for(int i = 0; i<hitBuffer.size()-resolution; i+=resolution){
std::vector<double>::const_iterator first = hitBuffer.begin() + i;
std::vector<double>::const_iterator last = hitBuffer.begin() + i + resolution;
std::vector<double> hitBufferBin(first, last);
rmsInEachBin[i/resolution] = calcRMS(hitBufferBin);
if(rmsInEachBin[i/resolution]>highestRMSValue){
highestRMSValue = rmsInEachBin[i/resolution];
highestRMSBin = i;
}
}
for(int j = 0 ; j < exactHit.size(); j++) {
exactHit[j]=hitBuffer[j+highestRMSBin];
}
return exactHit;
}
Please deallocate all the memory assigned using new or else it will cause memory leak and other bugs also might get introduced because of this .
http://cs.baylor.edu/~donahoo/tools/gdb/tutorial.html
You can debug using GDB , It will be handy to know a debugger if you are programming in C++ .
Hope this info will help you .

C++ Index variable changing radically in Debug Version [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have found a lot of answers that have to do with release version problems but none with the exact opposite.
I have a loop similar to the following:
while(index < 7 && FlagIsUp)
{
// process
Inner Loop
Inner Inner Loop
Array[index] = number;
++index;
}
Problem is that index changes radically from 6 (the last iteration) to 17209 for an int16_t and 1133165442 for size_t. NOTHING IN THE LOOP changes the index except the ++index. I replaced the while with a for and it still happens.
It only happens in debug mode, in release version it does finish without issues.
I also added volatile to the index and results were the same, it still overflowed.
Any ideas, pointers, would be appreciated. I can't provide a working copy of the bug so any theories are welcomed, I want to exhaust my options to find the problem.
EDIT:
Yes I'm sorry. I gave to little information.
First off I'm working with QNX Momentics Version: 4.6.0 and my debugger is part of the GNU Compiler Collection 4.3.3.
Now the inner loop is this:
cSignalNoIndex = 0;
while ((cSignalNoIndex < (2 * NO_PHASES + 1)) && !ShutDownFlag)
{
wSF0 = 0;
wExtSF = 0;
dwSFAcc = 0;
dwExtSFAcc = 0;
std::string SignalNo= " Waveform number " + Tool::toString(cSignalNoIndex);
Results[cSignalNoIndex].printWaveForm(SignalNo);
// Prepare Input vectors for FFT compute
cComponent = 0;
while (cComponent < (HCYCLE_SAMPLES << 1))
{
awReal[cComponent] = static_cast<int>(Results[cSignalNoIndex].WaveForm[cComponent/64][cComponent % 64]);
awImg[cComponent] = 0;
pwSource++;
cComponent++;
}
Results[cSignalNoIndex].printWaveForm(SignalNo);
// Get FFT (forward)
// Changed the wPwr from 7 to something else
iFft(&awReal[0], &awImg[0], wPwr, 1);
Results[cSignalNoIndex].printWaveForm(SignalNo);
// Compute magnitudes
//fMult = pInBlock3->fMult[cSignalNoIndex]; // Get Multiplier
fMult = 1;
for (cComponent = 0; cComponent < HCYCLE_SAMPLES && !ShutDownFlag; cComponent++)
{
int64_t dlOp = static_cast<int64_t>(awReal[cComponent]) * awReal[cComponent] + static_cast<int64_t>(awImg[cComponent]) * awImg[cComponent];
dlOp <<= 1; // Apply sqrt(2) term to result
dlOp = static_cast<int>(fMult * isqrt64(dlOp));
// Store into FFT object
oFFTMag3.wFFT[cSignalNoIndex][cComponent] = static_cast<int16_t>( dlOp );
// Set Base frequency magnitude and accumulate harmonics
if (cComponent == 1) // Base
{
wSF0 = dlOp;
if(cSignalNoIndex == 6)
{
wRefMagnitude = static_cast<int16_t> ( 0.4 * wSF0 );
}
if(awReal[1] != 0) // Also get phase for Base
{
dfPhase = std::atan((double)((float)awImg[1]/awReal[1])) * 180.0 / PI;
}
else
{
if(awImg[1] >= 0)
{
dfPhase = 90.0;
}
else
{
dfPhase = -90.0;
}
}
if(awReal[1] < 0) // convert to 2*PI range
{
dfPhase += 180.0;
}
else if(awImg[1] < 0)
{
dfPhase += 360.0;
}
//// THIS IS THE LINE
fPhase[cSignalNoIndex] = dfPhase; ////////// WTF! cSignalNoIndex = 6 - cComponent = 2
/// HERE cSignalNoIndex is overflown
}
}
You haven't really posted enough code but my best bet is Array[index] = number overwrites index at some point. The fact that it only happens sometimes (in your case, when debugging) is a good example of "undefined behavior".

Run-Time Check Failure #2 - Stack around the variable 'temp' was corrupted [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
When i am running this code I am getting below error as
Run-Time Check Failure #2 - Stack around the variable 'temp' was corrupted
int main()
{
UINT8 temp[7];
for (int i = 0; i <= 7; i++)
{
temp[i] = 0x01;
}
return 0;
}//The error falls here
Please help me.
you are accessing array out of boundry
change:
for (int i = 0; i <= 7; i++)
to
for (int i = 0; i < 7; i++)
Or more C++ way:
std::fill_n(temp, 7, 0x01);
the size of temp is 7 and the for loop reach 8 elements and not 7
change
for (int i = 0; i <= 7; i++)
by
for (int i = 0; i < 7; i++)
The array index in c start from 0. so if you go from index 0 to index 7 in your array that means you reach the 8th element in your array, but your array size is 7
The cycle should be excluding 7 - your array is of size 7, so there is no element with index 7 in it.
Declaring UINT8 temp[7]; creates an array of 7 variables. Starting from temp[0] to temp[6]
Your for loop however tries to access temp[7] which is undefined.
The below loop will work
for (int i = 0; i < 7; i++)
{
temp[i] = 0x01;
}
There are 7 elements in the array ([0..6]), your for loop tries to access 8 elements [0..7], therefore you get a corrupted stack.
for (int i = 0; i < 7; i++)
{
temp[i] = 0x01;
}
This will help you.. you are writing back to the temp again.. that is the error you are getting
Note that in C and C++, array indexes are 0-based. So, if you have an array of N items, valid index values are 0,1,2,...,(N-1).
In your case, N = 7, so valid index values are 0,1,2,3,4,5,6.
So, substitute <= with < in your for loop:
UINT8 temp[7];
for (int i = 0; i < 7; i++) // Use <, not <=
....
Moreover, there is a convenient _countof() macro available with VS in <stdlib.h>, which makes your code easier to read and maintain (instead of using the "magic number" 7 in your for loop):
for (int i = 0; i < _countof(temp); i++)
Using _countof(), if you change the size of the array, your loop code will still work, without modifying 7 to the new array size.
Note also that in C++11 it's possible to use range-based for loops (but they are not available in VC10/Visual Studio 2010, which you used as a tag in this question).
Note that if you want to fill a buffer with a given byte sequence you can use memset (a C-like way):
memset(temp, 0x01, sizeof(temp));
Or, more generally (even for elements larger than one byte), you can use C++ std::fill from <algorithm>:
fill(begin(temp), end(temp), 0x01);
Using an explicit algorithm like std::fill makes your code more readable, because it rises the "semantic level" of the source code (you just read "fill" instead of reading a "raw" for loop, the meaning of which you have to interpret).

Professionalise this code [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
I have been programming for about 3 years now and feel confident in my skills. But recently I began working alongside embedded systems and working on other peoples code and have begun to question how good my code is.
I see all these complex answers on SO and think I would have done that with a vector and if statements and wonder if I am any more than a beginner as I was self taught and don't really know my level.
So I was wondering if more experienced programmers could show me ho to do things better.
This is code I wrote to for an rpg game to pick a target to attack. using it as an example could you show me better/more advanced/professional ways of doing it.
int FindTarget(Player &player);
{
int aimPoint[5] = 0;
for(int i = 0; i <= 5; i++)
{
if(player.team[i].exist == true)
{
// set random starting point between 1 - 3
aimPoint[i] = random /3;
// add a point if you hve an elemental advantage minus if not
if(player.team[i].type == weak)
{
aimPoint += 1;
}
else if(player.team[i].type == strong)
{
aimPoint -= 1;
}
//add for front row minus for back
if(i == 1 || i== 3)
{
aimPoint += 1;
}
else
{
aimPoint -= 1;
}
}
}
return 0;
}
EDIT: If you don't have the time or effort to show me examples I would appreciate a good book that a beginner/intermediate could understand.
Comment #1:
This line starts at 0, and goes exactly once? Why is it a loop?
for(int i = 0; i <= 0; i++)
Comment #2:
Don't compare a boolean against true.
if(player.team[i].exist == true)
Just re-write it to:
if(player.team[i].exist)
Comment #3:
Professionals rarely use hardcoded values.
Why is this value 5?
int aimPoint[5] = 0;
Instead, make it clear:
int aimPoint[TARGET_SIZE] = 0;
Similarly, change
aimPoint[i] = random /3;
to:
aimPoint[i] = random /INITIAL_TARGET_VALUE;
This is pointless; it's not a loop, it's a single pass.
for(int i = 0; i <= 0; i++)
ahem since nobody mentioned it, let me point this one out:
int FindTarget(Player &player);
{
int aimPoint[5] = 0;
...
return 0
}
to roughly
void FindTarget(const Player &player)
{
std::vector<int> aimPoint(5, 0);
...
}
Also, since there is no knowing what the code should do (and how 'aimPoint' is related to teams; guessing doesn't help because none of it is used, aimPoint is discarded?), I don't have anything else than fixing the obvious breakage that was above
---- Edit from a comment
The handling of random seems misguided. Someone suggested that you might have meant random %3 + 1;
I noted that too but decided there is nothing to base the assumption on. Perhaps random is already an int in the range [3, 12).
Also, random % 3 won't yield a uniform distribution, so you'd need to do something else
For many applications, rand() will perform admirably when used correctly, but with the current sad state of affairs, rand() is very rarely used correctly.
The problem is that of distribution
Here is how I would write it.
void FindTarget(Player &player);
{
int aimPoint[5];
for(int i = 0; i <= 5; ++i)
{
if(!player.team[i].exist)
continue;
// set random starting point between 1 - 3
aimPoint[i] = random / 3;
// add a point if you hve an elemental advantage minus if not
switch(player.team[i].type) {
case weak:
++aimPoint[i];
break;
case strong:
--aimPoint[i];
break;
}
//add for front row minus for back
if(i == 1 || i== 3)
++aimPoint[i];
else
--aimPoint[i];
}
}
That piece of code:
// set random starting point between 1 - 3
aimPoint[i] = random /3;
don't get you random number between 1 and 3, try this:
aimPoint[i] = random % 3 + 1