0

数独を解くための単純な C++ アルゴリズムを作成しようとしています。異なる関数間でアドレス値を渡そうとしていますが、実行時にセグメンテーション エラーが発生します。(言うまでもなく、私はあまり経験がありません:))

コードは a[0] のアドレスをメイン関数に渡すことができ、メイン内のポインターを使用して値を読み取ることができます。関数を解決するためにアドレスを渡そうとすると、セグメンテーション違反が発生します。

(また、二次的な質問として、cout << *(a+5) などを使用して main で値を正しく読み取ることができます (main でコメントアウトされています) が、for ループを使用して格納されている 81 個の値すべてを出力しようとすると、それは無意味な値を与えます (コードでコメントアウトされています) コードは *(a+3) や a[3] のようなリテラルで機能しますが、int が関与する場合は機能しません for(int i, anything) 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";
    }
}
4

4 に答える 4

3

getInput(配列)のローカル変数にアドレスを返していますa。配列を引数としてこの関数に渡すことをお勧めします。別のオプションは、配列を動的に割り当ててから、プログラムが終了する前に解放するように注意することです。

于 2013-02-18T13:33:49.353 に答える
2

関数でa配列を作成します。get_input()static

int a[81];

する必要があります

static int a[81];

これは、関数が返された後もstatic割り当てられたメモリ ブロック ( array ) が割り当てられたままになることをキーワードが保証するためです。a通常、これは「まだ終わっていないため」です (たとえば、この方法で関数が呼び出された回数を数えることができます) が、合法的に、関数の戻り値を確実にするために使用することもできます。関数の終了後も存続します。

mainレベルで配列を宣言し、それへのポインターをget_input()andsolve()関数に渡す方がわずかに良いでしょう。そうすれば、配列が「プログラムの期間中存続する」ことをコードで明示的にすることができます。これは通常、良い習慣です。

于 2013-02-18T13:33:19.393 に答える
1
int a[81];

これはローカル メモリ割り当てであり、関数get_inputが戻ると解放されます。

代わりにポインタint* amalloc関数を使用して動的にメモリを割り当ててください!

malloc コマンドは次のようになります (よく覚えていれば):

int *a = (int *) malloc(sizeof(int)*81);
于 2013-02-18T13:35:07.357 に答える