簡體   English   中英

Qt中的“ EXC_BAD_ACCESS”

[英]“EXC_BAD_ACCESS” in Qt

基本上,下面是我的main.cpp,當我嘗試使用Qt的調試器運行它時,我收到“ EXC_BAD_ACCESS”錯誤(“無法訪問內存”)以及main第一行旁邊的箭頭(顯示“ Puzzle puzzle; )。 我以為這可能是我的Puzzle類的問題,但是當我將該行移動到其他地方時,調試器仍然留下了錯誤的訪問錯誤,調試器在main的第一行留下了相同的黃色箭頭。 是什么導致此錯誤? 半個小時前,我的程序運行良好,然后開始拋出此錯誤,自上次運行以來,我什至沒有修改代碼。 另外,這是我的第一個C / C ++項目,所以我對垃圾回收並不完全熟悉。 可能與內存泄漏或錯誤的內存分配有關嗎?

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

#include "piece.h"
#include "puzzle.h"
#include "state.h"


using namespace std;

//function prototypes
Puzzle initPuzzle(string*, int);
int countWords(string);

//count the number of words (separated by white space) in a string
int countWords(string s){
    int words = 0;
    char * temp = new char[s.size() + 1];
    copy(s.begin(), s.end(), temp);
    temp[s.size()] = '\0';
    temp = strtok (temp, " ");
    while (temp != NULL){
        words++;
        temp = strtok (NULL, " ");
    }
    delete(temp);
    return words;
}


//first checks validity of input
//if error(s), display appropriate message & exit program
//otherwise, returninstance of puzzle class from input file
//params: lines = array of strings, each of which is a line from input... size = # of elems in 'lines'
Puzzle initPuzzle(string * lines, int size){
    //create instance of puzzle
    //if bad piece found, throw it out
    //if first piece (Z) is invalid, the next piece becomes goal piece
    //if there are 0 valid pieces, display error to user and exit program
    Puzzle ret;
    int rows, cols;
    if(size < 2){
        //not enough lines for valid input
        cout << "Error: Input too short" << endl << "Exiting program..." << endl;
        exit(0);
    }
    istringstream iss(lines[0]);
    if((iss >> rows >> cols) && countWords(lines[0])==2){
        ret.rows=rows;
        ret.cols=cols;
    } else {
        cout << "Error: Invalid first line" << endl << "Exiting program..." << endl;
        exit(0);
    }
    if(rows < 1 || cols < 1){
        cout << "Error: Invalid dimensions" << endl << "Exiting program..." << endl;
        exit(0);
    }

    //now check the rest of the lines (ie the pieces)
    for(int i=1; i<size; i++){
        Piece newPiece;
        int startRow, startCol, width, height;
        char direction;
        istringstream iss(lines[i]);
        if(countWords(lines[i])==5 && (iss >> startRow >> startCol >> width >> height >> direction)){
            //row is formatted correctly, create instance of Piece
            newPiece = Piece(startRow, startCol, width, height, direction); //validate this piece later... if valid, add to pieces
        } else {
            //invalid row... entire input is invalid
            cout << "Error: Invalid row(s)" << endl << "Exiting program..." << endl;
            exit(0);
        }
        //now validate temporary piece...
        //first make sure piece doesn't fall outside of grid
        if(newPiece.startRow < 1 || newPiece.startCol < 1 || newPiece.startRow-1 > (rows - newPiece.height) ||
                newPiece.startCol-1 > (cols - newPiece.width)){
            //newPiece goes over the edge of the puzzle grid
            cout << "Piece goes beyond grid... Throwing it out" << endl;
            continue;
        }
        if(newPiece.direction != 'b' && newPiece.direction != 'h' && newPiece.direction != 'v' && newPiece.direction !='n'){
            //newPiece has invalid direction
            cout << "Piece has invalid direction... Throwing it out" << endl;
            continue;
        }
        if(ret.pieceCount!=0 && ret.pieceOverlap(newPiece)){
            //current piece overlaps existing one
            cout << "Piece overlaps another piece... Throwing it out" << endl;
            continue;
        }
        //if loop iteration reaches this point, piece is valid and can be added to puzzle
        cout << "Piece is good!" << endl;
        ret.addPiece(newPiece);
    }
    if(ret.pieceCount == 0){
        //all pieces were invalid
        cout << "Error: Puzzle has no pieces" << endl << "Exiting program..." << endl;
        exit(0);
    }

    //now assign id's to the pieces...
    for(int i=0; i<ret.pieceCount; i++){
        if(i==0){
            ret.pieces[i].id = 'Z';
        } else {
            ret.pieces[i].id = i;
        }
    }

    return ret;
}

int main()
{
    Puzzle puzzle;                              //single instance of puzzle class... initialized later after input & piece verification
    string inputFile;                           //name of input file... provided by user
    string line;                                //single line from input file
    string * inputLines = new string[9000];     //array of lines from the input file
    ifstream infile;
    int size = -1;                              //size of inputLines array, initialized to -1

    cout << "Enter name of input file: ";
    cin >> inputFile;
    infile.open(inputFile.c_str());
    if(infile){
        while(infile){
            size++;
            getline(infile,line);
            inputLines[size] = line;
        }
        infile.close();
    } else {
        cout << "Error: Input file could not be opened" << endl << "Exiting program" << endl;
        exit(0);
    }

    puzzle = initPuzzle(inputLines, size);  //now check the input for validity, and if valid, initialize puzzle


    return 0;
}

一個錯誤(實際上兩個錯誤)在countWords()函數中:

  • temp是使用new[]創建的,但使用delete取消分配的,它必須是delete[]new > deletenew[] -> delete[]並盡可能避免顯式動態內存管理)
  • 的值temp不是最初被分配值,當它必須delete[]荷蘭國際集團

通過使用std::istringstream代替計算字數,可以完全避免顯式動態內存分配:

std::istringstream in(s);
std::string ignored;
while (in >> ignored) words++;

其他要點:

  • 首選std::vector來進行顯式動態內存分配管理:

     std::vector<std::string> inputLines; // and use 'push_back()'. 
  • 始終立即檢查輸入操作的結果以確保成功:

     if (cin >> inputFile) { ifstream infile(inputFile); if (infile) { std::string line; while (std::getline(infile, line)) lines.push_back(line); } } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM