corsel
corsel

Reputation: 325

C++ segmentation fault while passing address values between functions

I am trying to write a simple C++ algorithm to solve sudoku. I am trying to pass address values between different functions but i get segmentation fault at runtime. (Needless to say, i am not quite experienced :))

The code does manage to pass the address of a[0] to main function and i can read values using pointers inside main. When i try to pass the address to solve function, it gives segmentation fault.

(Also as a secondary question, i can read values correctly in main, using cout << *(a+5) etc. correctly (commented out in main), but when i try to print all 81 values stored using a for loop, it gives out nonsense values (again, commented out in code). The code works with literals like *(a+3) or a[3], but does not when an int gets involved for(int i, whatever) cout << *(a+i);)

#include <iostream>
using namespace std;

int * get_input();
void solve(int *);

int main()
{
    int * a;
    a = get_input();
    //cout << *a << " " << *(a+1) << " " << *(a+2) << " " << *(a+3) << " " << *(a+4);
    //for (int i = 0 ; i < 81 ; i++) {if (i%9 == 0) cout << "\n"; cout << a[i] << " ";}
    solve(a);
    return(0);
}

int * get_input ()
{
    int a[81];
    getinput:
    for (int i = 0 ; i < 81 ; i++)  {a[i] = 0;}
    for (int i = 0 ; i < 81 ; i++)  {cin >> a[i];}
    print:
    for (int i = 0 ; i < 81 ; i++)
    {
        if (i%27 == 0){cout << "\n";}
        if (i%9 == 0) {cout << "\n";}
        if (i%3 == 0) {cout << "  " << a[i];}
        if (i%3 != 0) {cout << a[i];}
    }
    cout << "\n\nCheck:\n1- Fix\n2- Reset\n3- Confirm\n\n";
    int check = 0;
    cin >> check;
    if (check == 1)
    {   
        int input[3] = {-1, -1, -1};
        while (true)
        {
            cin >> input[0] >> input[1] >> input [2];
            if (input[1] == 0) goto print;
            a[(input[2]-1)+((input[1]-1)*9)] = input[0];
        }
    }
    if (check == 2) goto getinput;
    if (check == 3) return a;
}

void solve(int * a)
{
    bool matrix[9][9][9];
    for (int i = 0 ; i < 81 ; i++) {for (int j = 0 ; j < 9 ; j++) {matrix[(i-i%9)/9][i%9][j] = true;}}
    for (int i = 0 ; i < 81 ; i++)
    {
        if (a[i] == 0) continue;
        else
        {
            for (int j = 0 ; j < 9 ; i++)
            {
                matrix[(i-i%9)/9][j][a[i]] = false;
                matrix[j][i%9][a[i]] = false;
                matrix[((i-i%9)/9)-((i-i%9)/9)%3+j%3][i%9-(i%9)%3+(j-j%3)/3][a[i]] = false;
            }
        }
    }
    for (int i = 0 ; i < 9 ; i++)
    {
        for (int j = 0 ; j < 9 ; j++)
        {
            cout << matrix[i][j][1] << " ";
        }
        cout << "\n";
    }
}

Upvotes: 0

Views: 2268

Answers (4)

Floris
Floris

Reputation: 46365

Make the a array in your get_input() function static:

int a[81];

should be

static int a[81];

This works because the static keyword ensures that the allocated memory block (the array a ) will remain allocated after the function returns. Usually this is "because I'm not finished with it yet" (for example, you can count how many times your function is called this way), but it can also, legitimately, be used to ensure that the return value of a function survives the end of the function.

Marginally better would be to declare the array at the main level, and pass a pointer to it into the get_input() and solve() functions. That way you make it explicit in the code that the array will "live for the duration of the program" - and that's usually good practice.

Upvotes: 2

Dunes
Dunes

Reputation: 40703

You're problem is that you are returning a pointer to a locally declared variable. Don't do this. You should either pass in the variable as a parameter (eg. get_input(int[] arr, int length)` or allocate new memory on the heap for your array. The simplest is the former, the latter can get you into trouble as you have to manage your memory or you will get memory leaks.

Why do you need to do this? When you declare a[] in get_input it allocates the space for that variable on the stack. The stack is a long contiguous block of memory that is used to store a function's parameters, it's local variables and the address of the program that is calling the current function. When a function returns, all this memory is reclaimed for use by the next function call. That is, when solve is called it starts writing over the memory on the stack that was previously used by get_input.

You are quite lucky that you got a segmentation fault as it is sometimes possible for programs to continue operating even though their data has become utterly corrupted.

In summary: Declare your array in the main function and pass it to get_input to operate on.

Upvotes: 0

Paschalis
Paschalis

Reputation: 12291

int a[81];

This is a local memory allocation, and its freed when your function get_input returns.

Use a pointer int* a, and malloc function to allocate dynamically memory instead!

The malloc command may is like this(if i remember it well):

int *a = (int *) malloc(sizeof(int)*81);

Upvotes: 1

Ivaylo Strandjev
Ivaylo Strandjev

Reputation: 70929

You are returning an address to a local variable in getInput(the array a). I would suggest you pass the array as argument to this function. Another option is to allocate the array dynamically and then take care to free it before the program terminates.

Upvotes: 3

Related Questions