简体   繁体   中英

Why do I get a segmentation fault in my C++ sudoku checker?

I'm actually coding on codingame.com and I get a segmentation fault in my program that doesn't make sense to me.

I created a Grid class, which is basically a 2D array of (9*9) char and a couple of checking functions.

My public check() calls private checkLine(), checkRow() and checkSquare(). Each of these 3 in turn call 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;
}

As you can see, I put cerr statements to try to see what was happening.

When I try to run the program, this is what I get:

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

where line 37 is "vec.push_back(this->sudoku[line][j]);"

Could anyone send me in the right direction?

Edit: Sidenote, my checkNine() is not finished, it always returns true, but that's not the point.

Two errors:

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;
}

The nine vector holds char values. Those char values are character representations of the digits. However the tmp array assumes int versions of the digit, not char types.

In short, you are (for example) assuming that '2' == 2 , and that is not the case.

Thus you need to convert the char to the int version:

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

The other error is that tmp has to hold 10 digits, thus the array is too small. It should have a size of 10 , not 9 .

    array<int, 10> tmp;  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM