Been a long night, but stuck on this and now am getting "segmentation fault" in my compiler..
Basically I'm trying to display all the errors (the cout) needed. If there is more than one error, I am to display all of them.
bool validMove(const Square board[BOARD_SIZE][BOARD_SIZE],
int x, int y, int value)
{
int index;
bool moveError = true;
const int row_conflict(0), column_conflict(1), grid_conflict(2);
int v_subgrid=x/3;
int h_subgrid=y/3;
getCoords(x,y);
for(index=0;index<9;index++)
if(board[x][index].number==value){
cout<<"That value is in conflict in this row\n";
moveError=false;
}
for(index=0;index<9;index++)
if(board[index][y].number==value){
cout<<"That value is in conflict in this column\n";
moveError=false;
}
for(int i=v_subgrid*3;i<(v_subgrid*3 +3);i++){
for(int j=h_subgrid*3;j<(h_subgrid*3+3);j++){
if(board[i][j].number==value){
cout<<"That value is in conflict in this subgrid\n";
moveError=false;
}
}
}
return true;
}
If this is a chess board, then:
for(index=0;index<9;index++)
should be:
for(index=0;index<8;index++)
Or even better:
for(index=0;index<BOARD_SIZE;index++)
If you've got named constants, always use them in place of magic numbers.
check your indices. As you are using a fixed sized array, it might be an off-by-one error
To find out the exact line that is triggering your SEGFAULT, compile with the flag -ggdb (I'm assuming you are using GCC), and then run your program using gdb (using gdb ./name_of_the_program). When GDB starts up, use run to start the program. It will break at "main", and then execute continue. Let it run until it SEGFAULTs. Once it has segfaulted, execute backtrace (or, bt for short) to get a backtrace of the program execution. The backtrace should include the exact line that caused the SEGFAULT.
With the information that you get out of GDB, you should be able to debug your program. However, if you need more help than that, provide us with the output from backtrace so that we can be of more help.
1) Use this function instead of directly board[x][index], etc.:
const Square& GetSquare(
const Square board[BOARD_SIZE][BOARD_SIZE]&,
int x,
int y)
{
assert(x >= 0);
assert(x < BOARD_SIZE);
assert(y >= 0);
assert(y < BOARD_SIZE);
return board[x][y];
}
Test that you are on debug so that assert(false) gives an error message. Write assert(false), see the message, then delete this line. Without these assertions, I simply cannot trust your code.
2) Do not use magic numbers 9 and 3.
3) Take into account that int v_subgrid=x/3; may have a nonzero remainder, e.g., 7/3=2 and the remainder is 1. And 2/3=0. If this is what you want, ok. Just take it into account.
I expect your seg value might be in the following section... (as well as mentioned above (using 9 instead of BOARD_SIZE) for the proir two for-loops )...
for(int i=v_subgrid*3;i<(v_subgrid*3 +3);i++){
for(int j=h_subgrid*3;j<(h_subgrid*3+3);j++){
if(board[i][j].number==value){
cout<<"That value is in conflict in this subgrid\n";
moveError=false;
}
}
I would recommend you write some robust tests for functions such as yours (unit tests). Passing in values of X or Y that are set to BOARD_SIZE - 2 or above would mean indexing out of the array size of the board.
What I'm trying to get across is, code really need to be in place to stop indexing out of bounds,
hope this also helps,
Neil
Related
I have written the code which will print the slope from the coordinates of a line and then print it. but when I give input, my code is terminating. what is the problem?
#include<bits/stdc++.h>
using namespace std;
int main()
{
int x1,y1,x2,y2,m;
cin>>x1>>y1>>x2>>y2;
m=(y1-y2)/(x1-x2);
cout<<m;
}
Problem is probably here m=(y1-y2)/(x1-x2);. When x1==x2 you have division by zero, please add some checks.
Consider adding more corner tests, also note when x1 is equal to x2 you will face division by zero error, so you should modify your program with if statement to check that they are not equal.
so you should add this to your code:
if(x1==x2){
cout<<"Error division by zero"<<endl;
return 1;
}
I tested your code using c++ compiler online and it worked.
You may have a compiler error or something else.
#include<bits/stdc++.h>
#define big 1000000007
using namespace std;
long long n,k;
int fobo(int);
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
k=fobo(n)%big;
printf("%d",k);
printf("\n");
}
return 0;
}
int fobo(int m)
{
if(m==1)
return 0;
if(m==2)
return 1;
return 3*fobo(m-1)+2*fobo(m-2)+5;
}
The above code is for printing the sum of a special kind of Fibonnacci series following the relation given in the recurrence relation inside the function fobo . The code works fine on my machine but on testing in any online judge , the same code shows SIGSEGV error. There is no use of any arrays in the program , accessing unknown memory that i know of. I guess these are the some of the major requirements for having a SIGSEGV error. I cant find any in here . Please help me in resolving or finding the error.
If I had to guess, this looks like a stack overflow error. Try feeding 0 into fobo. When that happens, your base cases don't trigger because neither one checks for zero. You then call fobo(-1) and fobo(-2), which will start a chain of recursive calls of the form fobo(-2), fobo(-3), fobo(-4), etc. until you eventually overflow the stack.
To fix this, consider adding in a new base case for 0 in your code, or alternatively put in a general check to handle the case where the input is negative.
EDIT: Based on the comments, I think the main issue here is that if you call this function with a large input, you'll get a stack overflow before the recursion terminates. To address this, consider computing your values bottom-up using dynamic programming. I suspect that's what the question is ultimately trying to get at. Alternatively, use a different recursive formulation amenable to tail call elimination. If you're not familiar with these techniques, look online - you'll learn a lot in the process!
I have a binarysearch function with interface as follows:
bool binarysearch(int* array, int size, int findnum) {
doBinarySearch(array, 0, (size-1), findnum);
}
The code for doBinarySearch is:
bool doBinarySearch(int* array, int start, int end, int findnum) {
if (end <= start)
return false;
int mid = (start+end)/2;
if (array[mid] == findnum) {
return true;
} else if (findnum < array[mid]) {
return doBinarySearch(array, start, mid, findnum);
} else {
return doBinarySearch(array, mid+1, end, findnum);
}
}
I wrote a unit test to test the above function. If I call binarysearch with empty array and wrong size from main, the code seg. faults as expected. E.g.
int main() {
int *array;
binarysearch(array, 10, -1);
}
But if I write a unit test class and have a function which does the above, then the binary search does not crash. Any idea, why the different behavior:
class TestBinarySearch {
public:
void testEmptyArray() {
int *array;
binarysearch(array, 10, -1);
}
};
int main() {
TestBinarySearch testObj;
// below line does not cause seg fault. and -1 is found for some reason
testObj.testEmptyArray();
}
Another question - Is there any way to detect the seg. fault if somebody calls the function with wrong size? I see some examples of using signals to catch that, but after that except exiting the program, can anything else be done?
Both ways of writing it invoke undefined behavior. And undefined behavior can be anything. That it crashes in one you should be grateful for; that it "succeeds" in the other is unfortunate but very possible. The behavior might even change next time you reboot your computer or run the program, who knows. It's undefined.
If you're on Linux, run both programs under valgrind and see what it says. It may report errors even when there is no crash.
Reading beyond the end of an array is undefined behaviour, as John has said. The compiler can do whatever it likes; your software may crash, it may process rubbish data, it may reformat your hard drive (at least in standards conformance terms).
There is no way to detect that the wrong size for the array has been given.
The right way to fix this is to pass in one of the STL containers and not a C array. At a minimum, you could rewrite the binarySearch function like this:
bool binarysearch(std::vector<int> array, int findnum) {
doBinarySearch(&array[0], 0, array.size()-1, findnum);
}
This situation is not an empty array, this is an unitialised pointer variable. Dereferencing an uninitialised pointer is Undefined Behaviour. It's a program error, and you cannot protect against it.
Undefined Behaviour means that anything might happen. Crash one time, not another, it's all as expected.
With this API both your caller and your unit test must ensure that the array passed is valid and at least as long as the length passed, and there is absolutely no way to programmatically check that this is so.
You could consider changing the API to use an STL collection instead, but that would be a different question.
BTW you have an unrelated bug. The code should say:
if (end < start) return false;
hi guys can anyone tell me what's wrong with my 3-way mergesort code?the code I wrote can only sort 4 numbers if you give it more than 4 numbers(by changing size) it ends up with stack overflow error,here is the code:
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
const int size=4;
vector <int> s(size);
void merge(int,int,int);
void mergesort(int,int);
int main(){
for(int i=0;i<size;i++){
cout<<"enter number "<<i+1<<":";
cin>>s.at(i);
}
system("CLS");
cout<<"here are the unsorted numbers:\n";//prints the input values so U can see'em
for(int j=0;j<size;j++)
cout<<s.at(j)<<".";
mergesort(0,size-1);//calls mergesort
cout<<"\nhere are the sorted numbers:\n";
for(int j=0;j<size;j++)
cout<<s.at(j)<<".";
cin.get();
cin.get();
return 0;
}
void merge(int low,int one_third,int high){
int i=low;
int j=one_third+1;
int k=0;
int length=(high-low)+1;
vector <int> u(length,0);
if(k<length){
while((i<=one_third)&&(j<=high)){
if(s.at(i)<=s.at(j)){
u.at(k)=s.at(i);
i++;
k++;
}//end for
else{
u.at(k)=s.at(j);
j++;
k++;
}//end elseif
}//end while
if(j>high)
while(i<=one_third)
{
u.at(k)=s.at(i);
i++;
k++;
}
if(i>one_third)
while(j<=high)
{
u.at(k)=s.at(j);
j++;
k++;
}
for(int n=low;n<k;n++)
s.at(n)=u.at(n);
}
}//end if
void mergesort(int low,int high){
if(low<high){
int one_third=(high-low)/3;//division,it's 3-way mergesort so obviously it's divided by 3
int two_third=2*one_third;
mergesort(low,one_third);
mergesort(one_third+1,two_third);
mergesort(two_third+1,high);
merge(low,one_third,two_third);
merge(low,two_third,high);
}//end if
}
at this point I guess I'm done thinking,Any answer/idea would be appreciated.
Here's a partial inspection of your code. I believe there is an issue debugging a 3 way merge sort with 4 values. You should use more values, such as 6 or 7.
Spaces not tabs for StackOverflow
I'll take a guess that the indentation is because you use tab characters in your code and pasted directly. You'll want to expand the tabs in your next post.
Precompiled Headers
Is your project huge? Does it significantly reduce the build time when you change a header or modify the source code?
I find that stdafx usually is more of a hassle and the time spent resolve defects it causes negates any potential savings by having a precompiled header.
Function prototypes should use named parameters
Can you tell the purpose of the different parameters in your declaration of merge and mergeSort?
Ambiguity breeds defects. 'nuff said.
Main function declared wrong.
The main function always returns an int to the operating system, always. The OS can ignore it.
This mechanism is so that script files can execute your program and test for errors.
Readability prevents defects
Invest in spaces around operators. The time saved by sacrificing spaces is negligible. The debugging time saved by having easy to read code is tremendous, especially when having other people review or inspect your code.
Use intermediate variables
Intermediate variables help clarify your program. They don't cost memory when you tell the compiler to optimize. During debugging, they can help show values during calculations.
The typical idiom for reading into a vector is:
int value;
cin >> value;
s.push_back(value);
The at method may have an overflow issue (or at least your not checking for out of bounds issues). The push_back method will cause the vector to expand as necessary.
Meaningful variable names reduces defects
The variable s has no meaning. Something like original_values or number_container are more descriptive. And again, variable name lengths have nothing to do with improving performance. Readable names help reduce the defects injected.
Not checking state of cin
If I enter "Lion" in response to your 2nd prompt, what will be in the 2nd slot of the array?
Don't trust the Users, they aren't perfect.
Don't clear the screen
It may contain useful data, such as the actual numbers entered. So when you are debugging, and want to know what the User actually typed in, it will be lost and gone forever.
Why cin.get twice?
You are asking the User for input without prompting. And twice. Bad Karma between your program and the User.
See cin.ignore if you want to ignore characters until a specific one is received. Something like this perhaps:
cout << "Paused. Press Enter to continue.\n";
cin.ignore(100000, '\n');
Magic numbers
In function mergesort, you use the numbers 2 and 3. Why? What's their purpose?
Redundant comments
Most programmers realize that the '/' character in a math expression is division. The comment is redundant.
Also, why divide by 3? It's a nasty number. Do you realize you are performing integer division and your product will be truncated? For example: 1/3 == 2/3 == 0.
USE A DEBUGGER
Lastly, a lot of your program's functionality can be verified easier and quicker by using a debugger. A debugger allows you to execute a statement and see the variable values. You can set breakpoints to stop execution at different places. It's a worthwhile educational investment, start now.
A "classic" 3 way merge sort merges runs 3 at a time, alternating between a source and destination array (or vector or list). The code needs to perform up to 3 compares in order to determine the "smallest" of 3 values from each of the 3 runs, then move the smallest value from it's corresponding run to the destination array. The code also has to handle the case where the end of a run is reached, leaving only 2 runs to merge, then the case where the end of the second run is reached, in which case the rest of the third run is moved to the destination array.
For a ram based sort, I'm not sure this is any faster than a normal 2 way merge. For an external sort, with multiple devices or very large read and writes, then a k way merge with k up to 12 or 16 will be faster.
When I'm trying to debug a C program written on Linux machine (right now, I'm using Visual C++ Express), I first get a stack overflow error. So when I clicked continue, I got another error message,
Access violation reading location 0x00030000
So I decide to debug step by step. So when I try it, it shows me the error
There is no source code available for the current location.
What is the reason for this error?
The Code
#if 1
while(1)
#endif
{
fillList();
#if 1
{
op_ds_bulk(ops, &total, 1);
temp = res("Bulk Write:", total, fp);
index = 0;
}
#endif
void op_ds_bulk(u_int ops, u_int * totalp, int update)
{
char encode_db[] = "encode";
if(update)
{
database_insert_bluk(list, ops);
database_sync();
*totalp = ops;
}
else
{
CHUNK prefetch[4096];
int random = rand() % (h-ops+1);
__os_clock(NULL, &start_time.secs, &start_time.usecs);
database_select_end(65546, random, prefetch, ops);
__os_clock(NULL, &end_time.secs, &end_time.usecs);
*totalp = ops;
}
}
}
The invalid access might occur somewhere in the standard library code. The source for that is not available in the Express edition.
You might check the call stack for the part of your code that calls a library function, and work it from there.
Some time ago I had a similar problem, maybe it is related to yours?
I had an array on the stack (you have one too - prefetch) and I accidently cleared it too far (out of bounds of the array), removing whatever information was beyond the array.
When you call a function, the return address is also stored on the stack (computer must know where to return from a function). Since I have cleared that, the program jumped under address 0x0 and SegFault-ed. When debugging, I also got a message "there is no source code at current location", because "current location" was 0x0 and of course there was no code there.
So I suspect that you go out-of-bounds on some array which is on the stack.
By looking at your code, I see two suspicious things:
The size of your prefetch array is 4096, but you call database_select_end with parameter 65546. Maybe it is ok (no idea what that function does) but maybe it is not ;)
65546 is not a power of 2. 2^16=65536
I solved the problem by writing the same code with a different function name. It's so weird for me because it solved my problem. I don't know why.