简体   繁体   English

Qt中的“ EXC_BAD_ACCESS”

[英]“EXC_BAD_ACCESS” in Qt

Basically, below is my main.cpp and when I try to run it with Qt's debugger, I get the "EXC_BAD_ACCESS" error ("Could not access memory") along with an arrow next to the first line of main (where it says Puzzle puzzle; ). 基本上,下面是我的main.cpp,当我尝试使用Qt的调试器运行它时,我收到“ EXC_BAD_ACCESS”错误(“无法访问内存”)以及main第一行旁边的箭头(显示“ Puzzle puzzle; )。 I thought it might be a problem with my Puzzle class, but when I moved that line elsewhere, I still got the bad access error with the debugger leaving the same yellow arrow by the first line of main . 我以为这可能是我的Puzzle类的问题,但是当我将该行移动到其他地方时,调试器仍然留下了错误的访问错误,调试器在main的第一行留下了相同的黄色箭头。 What's causing this error? 是什么导致此错误? My program ran fine half an hour ago, and then started throwing this error and I haven't even modified the code since it last worked. 半个小时前,我的程序运行良好,然后开始抛出此错误,自上次运行以来,我什至没有修改代码。 Also, this is one of my first projects in C/C++, so I'm not totally familiar with garbage collection. 另外,这是我的第一个C / C ++项目,所以我对垃圾回收并不完全熟悉。 Could it be something to do with memory leaks or bad memory allocation? 可能与内存泄漏或错误的内存分配有关吗?

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

One mistake (two really) is within the function countWords() : 一个错误(实际上两个错误)在countWords()函数中:

  • temp is created using new[] but is deallocated use delete , it must be delete[] ( new -> delete and new[] -> delete[] and avoid explicit dynamic memory management whenever possible) temp是使用new[]创建的,但使用delete取消分配的,它必须是delete[]new > deletenew[] -> delete[]并尽可能避免显式动态内存管理)
  • the value of temp is not the value it was originally assigned which it must be when delete[] ing 的值temp不是最初被分配值,当它必须delete[]荷兰国际集团

Explicit dynamic memory allocation can be avoided completely by using a std::istringstream instead to count the words: 通过使用std::istringstream代替计算字数,可以完全避免显式动态内存分配:

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

Other points: 其他要点:

  • prefer std::vector to explicit dynamic memory allocation management: 首选std::vector来进行显式动态内存分配管理:

     std::vector<std::string> inputLines; // and use 'push_back()'. 
  • always check result of input operations immediately to ensure success: 始终立即检查输入操作的结果以确保成功:

     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