【问题标题】:Why do I get a segmentation fault in my C++ sudoku checker?为什么我的 C++ 数独检查器出现分段错误?
【发布时间】:2020-08-23 01:39:13
【问题描述】:

我实际上是在 codingame.com 上编码,但我的程序中出现了对我来说没有意义的分段错误。

我创建了一个 Grid 类,它基本上是一个由 (9*9) 字符组成的二维数组和几个检查函数。

我的 public check() 调用 private checkLine()、checkRow() 和 checkSquare()。这 3 个中的每一个依次调用 checkNine()。

#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <algorithm>

using namespace std;

class Grid
{
    public:
        Grid(string str)
        {
            for (int i = 0; i < 81; i++)
            {
                this->sudoku[i/9][i%9] = str[i];
            }
        }
        string check()
        {
            bool result = true;
            for (int i = 0; i < 9; i++)
            {
                result = result && checkLine(i) && checkRow(i);
            }
            return result ? "true" : "false";
        }
    private:
        bool checkLine(int line)
        {
            cerr << "line:" << line << endl;
            vector<char> vec;
            for (int j = 0; j < 9; j++)
            {
                vec.push_back(this->sudoku[line][j]);
            }
            return checkNine(vec);
        }
        bool checkRow(int row)
        {
            cerr << "row:" << row << endl;
            vector<char> vec;
            for (int k = 0; k < 9; k++)
            {
                  vec.push_back(this->sudoku[k][row]);
            }
            return checkNine(vec);
        }
        bool checkNine(vector<char> nine)
        {
            array<int, 9> tmp;
            tmp.fill(0);
            for(int m = 0; m < 9; m++)
            {
                tmp[nine[m - '0']] = tmp[nine[m - '0']] + 1;
            }

            return true;
        }
        char sudoku[9][9];
};

int main()
{
    string str;
    str = "123456789456789123789123456912345678345678912678912345891234567234567891567891234";

    Grid grid(str);
    cout << grid.check() << endl;
}

如您所见,我放置了 cerr 语句来尝试查看发生了什么。

当我尝试运行程序时,我得到的是:

Erreurs
Segmentation fault.
at new_allocator.h. function __gnu_cxx::new_allocator<char>::deallocate (this=0x7fffffffe8d0, __p=0x55565556ef50 <error: Cannot access memory at address 0x55565556ef50>) on line 128
at alloc_traits.h. function std::allocator_traits<std::allocator<char> >::deallocate (__a=..., __p=0x55565556ef50 <error: Cannot access memory at address 0x55565556ef50>, __n=18446744069414584329) on line 470
at stl_vector.h. function std::_Vector_base<char, std::allocator<char> >::_M_deallocate (this=0x7fffffffe8d0, __p=0x55565556ef50 <error: Cannot access memory at address 0x55565556ef50>, __n=18446744069414584329) on line 351
at stl_vector.h. function std::_Vector_base<char, std::allocator<char> >::~_Vector_base (this=0x7fffffffe8d0, __in_chrg=<optimized out>) on line 332
at stl_vector.h. function std::vector<char, std::allocator<char> >::~vector (this=0x7fffffffe8d0, __in_chrg=<optimized out>) on line 680
at Answer.cpp. function Grid::checkLine (this=0x7fffffffe950, line=0) on line 37
at Answer.cpp. function Grid::check[abi:cxx11]() (this=0x7fffffffe950) on line 24
at Answer.cpp. function main () on line 94
Sortie standard :
line:0
row:0

第 37 行是“vec.push_back(this->sudoku[line][j]);”

谁能送我正确的方向?

编辑:旁注,我的 checkNine() 没有完成,它总是返回 true,但这不是重点。

【问题讨论】:

  • 你得到line:0 row:1 之前没有任何其他输出?
  • 请提供重现错误的minimal reproducible example(实际上确保它重现了错误)。如果您需要帮助制作一个,请告诉我们。
  • @CarlosN 正是,这是我仅有的两个输出。
  • 您希望我们为您调试您的程序吗?调试会话的结果是什么?您是否尝试过在第 45 行设置断点并检查变量?
  • 我没有看到程序。我看到一个名为Grid 的类,它带有成员函数。程序需要使用Gridmain 函数。

标签: c++ vector segmentation-fault


【解决方案1】:

两个错误:

bool checkNine(vector<char> nine)
{
    array<int, 9> tmp;  // <-- Too small, it has to hold 10 digits
    tmp.fill(0);
    for (int i = 0; i < 9; i++)
    {
        tmp[nine[i]] = tmp[nine[i]] + 1; // <-- Out of bounds access
    }
    return true;
}

nine 向量保存char 值。那些char 值是数字的字符表示。但是 tmp 数组假定数字的 int 版本,而不是 char 类型。

简而言之,您(例如)假设'2' == 2,但事实并非如此。

因此您需要将char 转换为int 版本:

tmp[nine[i] - '0'] = tmp[nine[i] -'0'] + 1; 

另一个错误是tmp 必须保存 10 位,因此数组太小。它的大小应该是10,而不是9

    array<int, 10> tmp;  

【讨论】:

  • 谢谢!事实上,这是我在之前的评论中提到的“明显”错误之一。我仍然有完全相同的错误,但现在 cerr 输出为 row:0。
  • 那么分段错误不再出现?
  • 哦不,它仍然存在,唯一的变化是 row:0 而不是 row:1。
  • 那么你需要提供数据——见主要部分的评论。
猜你喜欢
  • 2018-01-07
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多