Qt中的“EXC_BAD_ACCESS”

时间:2013-02-20 21:17:36

标签: c++ qt

基本上,下面是我的main.cpp,当我尝试用Qt的调试器运行它时,我得到“EXC_BAD_ACCESS”错误(“无法访问内存”)以及主要第一行旁边的箭头(其中)它说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;
}

1 个答案:

答案 0 :(得分:3)

一个错误(两个真的)在函数countWords()中:

  • temp是使用new[]创建的,但已取消分配使用delete,必须为delete[]new - &gt; delete和{ {1}} - &gt; new[]并尽可能避免显式动态内存管理)
  • delete[]的值最初分配的值temp
  • 时必须是

使用std::istringstream代替计算单词,可以完全避免显式动态内存分配:

delete[]

其他要点:

  • 更喜欢std::istringstream in(s); std::string ignored; while (in >> ignored) words++; 显式动态内存分配管理:

    std::vector
  • 始终立即检查输入操作的结果以确保成功:

    std::vector<std::string> inputLines; // and use 'push_back()'.