2014-10-07 63 views
-2

我寫了這個程序作爲我的一位教授的副項目。它從給定的文本文件中的9x9塊中讀取Sudoku拼圖,然後使用遞歸的回溯鏈表清晰地解決它。這樣做很好,但是我總是在執行結束時出現段錯誤。程序結束時的段錯誤

#include <iostream> 
#include <fstream> 
#include <stdlib.h> 

using namespace std; 

int ctoi(char c); 
void printBoard(); 
int board[9][9]; 

class Node 
{ 
    public: 
    int x_, y_; 
    int value; 
    Node* next_; 
    bool checkAllowed(); 
    bool processNextNode(); 
    bool requiredValue; 
}; 

bool Node::checkAllowed() 
{ 

    int checkVal = value; 
    //Check vertically 
    for(int i = 0; i < 9; i++) 
    { 
     if(i != y_) 
     { 
      int compareVal = board[x_][i]; 
      if(board[x_][i] == value) 
      { 
       return false; 
      } 
     } 
    } 

    //Check horizontally 
    for(int i = 0; i < 9; i++) 
    { 
     if(i != x_) 
     { 
      if(board[i][y_] == value) 
      { 
       return false; 
      } 
     } 
    } 

    //Check 3x3 block 
    int offsetX = x_ - x_ % 3; 
    int offsetY = y_ - y_ % 3; 

    for (int i = 0; i < 9; i++) 
    { 
     int x, y; 
     x = offsetX + i % 3; 
     y = offsetY + i/3; 
     if (x != x_ && y != y_) 
     { 
      if(board[x][y] == value) 
      { 
       return false; 
      } 
     } 
    } 
    return true; 
} 

bool Node::processNextNode() 
{ 
    if(requiredValue) 
    { 
     if(next_ == 0) 
     { 
      return true; 
     } 
     else 
     { 
      return next_ -> processNextNode(); 
     } 
    } 
    for(int i = 1; i <= 9; i++) 
    { 
     value = i; 
     if(checkAllowed()) 
     { 
      board[x_][y_] = value; 
      printBoard(); 
      if(next_ == 0) 
      { 
       return true; 
      } 
      else if(next_ -> processNextNode()) 
      { 
       return true; 
      } 
     } 
    } 
    return false; 
} 

int main() 
{ 
    char* fileName; 
    ifstream fin; 
    Node* head; 
    Node* next = new Node(); 
    head = next; 

    cout << "Enter file name : "; 
    cin >> fileName; 

    fin.open(fileName); 

    if(fin == 0) 
    { 
     cout << "File does not exist" << endl; 
     return 1; 
    } 

    for(int i = 0; i < 9; i++) 
     { 
     char* line; 
     fin >> line; 
     for(int j = 0; j < 9; j++) 
     { 
      board[j][i] = ctoi(line[j]); 
      if(board[j][i] == 0) 
      { 
       next -> requiredValue = false; 
      } 
      else 
      { 
       next -> requiredValue = true; 
      } 
      next -> x_ = j; 
      next -> y_ = i; 
      next -> value = board[j][i]; 
      if(i == 8 && j == 8) 
      { 
       next -> next_ = 0; 
      } 
      else 
      { 
       next -> next_ = new Node; 
       next = next -> next_; 
      } 
     } 
    } 

    printBoard(); 

    bool good = head -> processNextNode(); 

    printBoard(); 
    if(!good) 
    { 
     cout << "Puzzle is unsolveable." << endl; 
    } 

    return 0; 
} 

int ctoi(char c) 
{ 
    if(c == '.') 
    { 
     return 0; 
    } 
    return (int) c - (int) '1' + 1; 
} 

void printBoard() 
{ 
    system("cls"); 
    for(int i = 0; i < 9; i++) 
    { 
     for(int j = 0; j < 9; j++) 
     { 
      cout << board[j][i]; 
     } 
     cout << endl; 
    } 
} 

我是新來的C++指針和我想這可能是刪除一些元素的不當的結果。任何洞察力將不勝感激。

+0

使用'的std :: string'而不是未初始化的'字符*'持有字符串。 – 2014-10-07 04:13:30

+0

但是在你的程序中似乎沒有任何手動的'delete's(儘管事實上應該像使用'new'來分配'Node'一樣)。 – 2014-10-07 04:13:45

+0

手動刪除fileName字符串的竅門。幾個月前,我從Java到C++,我仍然在搞清楚。 – 2014-10-07 04:21:25

回答

2

這行代碼:

cin >> fileName; 

指「閱讀來自標準輸入的字符串,並通過fileName把該字符串在所述位置處的內容指向」。不幸的是,fileName是一個未初始化的指針,所以它覆蓋了內存中的隨機字節。

由於它一直等到進程退出到段錯誤,所以被覆蓋的內容似乎可能是進程清理處理程序的一部分。

解決這個問題的最簡單的方法是不是寫:

#include <string> 
... 
std::string fileName; 
... 
cin >> fileName; 
fin.open(fileName);