0

我正在尝试编写一个简单的 C++ 算法来解决数独问题。我正在尝试在不同函数之间传递地址值,但在运行时出现分段错误。(不用说,我不是很有经验:))

该代码确实设法将 a[0] 的地址传递给 main 函数,我可以使用 main 中的指针读取值。当我尝试传递地址来解决函数时,它会出现分段错误。

(作为第二个问题,我可以在 main 中正确读取值,使用 cout << *(a+5) 等正确(在 main 中注释掉),但是当我尝试打印使用 for 循环存储的所有 81 个值时,它给出了无意义的值(再次,在代码中注释掉)。该代码适用于 *(a+3) 或 a[3] 之类的文字,但当涉及 int 时则不起作用 for(int i, 不管) 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关键字确保分配的内存块(数组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 回答
0

你的问题是你正在返回一个指向本地声明变量的指针。不要这样做。您应该将变量作为参数传递(例如 get_input(int[] arr, int length)` 或在堆上为您的数组分配新内存。最简单的是前者,后者可能会给您带来麻烦必须管理你的内存,否则你会得到内存泄漏。

为什么需要这样做?当您在其中声明 a[] 时,get_input它会在堆栈上为该变量分配空间。堆栈是一个长的连续内存块,用于存储函数的参数、局部变量和调用当前函数的程序的地址。当一个函数返回时,所有这些内存都会被回收以供下一个函数调用使用。也就是说,当solve被调用时,它开始在堆栈上写入之前使用的内存get_input

您很幸运遇到了分段错误,因为有时程序可能会继续运行,即使它们的数据已完全损坏。

总结:在主函数中声明您的数组并将其传递给get_input进行操作。

于 2013-02-18T13:44:53.113 回答