Qt - 分段故障

时间:2013-11-28 20:58:52

标签: c++ qt segmentation-fault sigsegv qpixmap

我搜索了高低的答案,我知道我的错(退出代码:-1073741819)是由一般访问冲突引起的,但无法弄清楚我的代码是如何产生此错误的。

为了让事情变得更加奇怪,这个程序在不到一周前编译并运行,尽管有一些错误。我没有更改任何代码,今天打开它以快速查看我的代码,因为我明天正在接受采访,并且会弹出这个错误。

SIGSEGV发生在item.cpp类的第23行,return ItemPicture所在的位置。

对于代码墙感到抱歉,但最好包含所有内容。提前谢谢!

以下是该计划的完整代码:

inventory.h

#ifndef INVENTORY_H
#define INVENTORY_H

#include <iostream>
#include <vector>
#include "item.h"

using namespace std;

class Inventory
{
private:
    vector<Item> inventory;
    vector<string> inventoryItems;
public:
    Inventory();
    void deleteItem(int i);
    Item *getItem(int i);
    bool hasItem(int i);
    void addItem(Item *inItem);
    int getSize();
    bool hasString(string inString);
};

#endif // INVENTORY_H

inventory.cpp

#include "inventory.h"
#include "item.h"

using namespace std;

Inventory::Inventory()
{
}

void Inventory::addItem(Item *inItem)
{
    inventory.push_back(*inItem);
    inventoryItems.push_back(inItem->getDescription());
}

void Inventory::deleteItem(int i)
{
    inventory.erase(inventory.begin()+i);
}

bool Inventory::hasItem(int i){
    if(inventory.size() > i){
        return true;
    }
    return false;
}

Item* Inventory::getItem(int i){
    return &inventory[i];
}

int Inventory::getSize(){
    return inventory.size();
}

bool Inventory::hasString(string inString){
    if(std::find(inventoryItems.begin(), inventoryItems.end(), inString) != inventoryItems.end()){
        return true;
    }else{
        return false;
    }
}

item.h

#ifndef ITEM_H
#define ITEM_H
#include<QMainWindow>
using namespace std;

class Item
{
public:
    Item(string inDescription, QPixmap *pic, int value);
    int getValue();
    void setValue(int inValue);
    string getDescription();
    QPixmap getPic();
    void setPic(QPixmap pic);

private:
    QPixmap itemPicture;
    int value;
    string description;
};

#endif // ITEM_H

item.cpp

#include "item.h"

Item::Item(string inDescription, QPixmap *pic, int inValue){
    itemPicture = *pic;
    value = inValue;
    description = inDescription;
}

int Item::getValue(){
    return value;
}

void Item::setValue(int inValue){
    value = inValue;
}

string Item::getDescription(){
    return description;
}


QPixmap Item::getPic(){
    return itemPicture; //ERROR OCCURS HERE
}

void Item::setPic(QPixmap inPic){
    itemPicture = inPic;
}

room.h

#ifndef ROOM_H
#define ROOM_H
#include<QMainWindow>
#include <map>
#include <string>
#include <vector>
#include "item.h"

using namespace std;
using std::vector;

class Room
{
private:
    string description;
    int roomNum;
    map<string, Room*> exits;
    vector <Item> itemsInRoom;
    QPixmap roomImage;
    bool locked;

public:
    Room(int roomNum, string description, QPixmap *pic);
    void setExits(Room *north = NULL, Room *east = NULL, Room *south = NULL, Room *west = NULL);
    void setImage(QPixmap *pic);
    QPixmap getImage();
    string shortDescription();
    string longDescription();
    Room *nextRoom(string direction);
    Item *getItem(int i);
    void deleteItem(int i);
    bool hasItem(int i);
    void addItem(Item*inItem);
    int getRoomNum();
    int getSize();
    bool getLocked();
    void setLocked(bool value);
};

#endif // ROOM_H

room.cpp

#include "room.h"
#include "inventory.h"
#include <QPixmap>

Room::Room(int roomNum, string description, QPixmap *pic) {
    this->description = description;
    this->roomImage = *pic;
    this->roomNum = roomNum;

    if(roomNum == 7){
        locked = true;
    }else{
        locked = false;
    }
}

void Room::setExits(Room *north, Room *east, Room *south, Room *west) {
    if (north != NULL)
        exits["north"] = north;
    if (east != NULL)
        exits["east"] = east;
    if (south != NULL)
        exits["south"] = south;
    if (west != NULL)
        exits["west"] = west;
}

string Room::shortDescription() {
    return description;
}

string Room::longDescription() {
    if(itemsInRoom.size()>0)
        return "You are in " + description+". There may be items in this room that could help you..";
    else{
        return "You are in " + description;
    }
}

bool Room::hasItem(int i){
    if(itemsInRoom.size() > i){
        return true;
    }
    return false;
}

void Room::addItem(Item *inItem) {
    itemsInRoom.push_back(*inItem);
}

void Room::deleteItem(int i) {
    itemsInRoom.erase(itemsInRoom.begin()+i);
}

Item* Room::getItem(int i){
    return &itemsInRoom[i];
}

int Room::getRoomNum(){
    return roomNum;
}

void Room::setImage(QPixmap *pic){
   roomImage = *pic;
}

QPixmap Room::getImage(){
  return roomImage;
}

int Room::getSize(){
  return itemsInRoom.size();
}

Room* Room::nextRoom(string direction) {
    map<string, Room*>::iterator next = exits.find(direction);
    if (next == exits.end())
        return NULL;
    return next->second;
}

bool Room::getLocked()
{
    return locked;
}

void Room::setLocked(bool value)
{
    locked = value;
}

rungame.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFileInfo>
#include "room.h"
#include "item.h"
#include "inventory.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void createRooms();
    void play();
    void display();
    void setItems();
    void takeItems(int i);
    void dropItems(int i);
    void displayInventory();
    void setVisibleItems();
    Room *lockedRoom;

private slots:
    void on_northButton_clicked();
    void on_eastButton_clicked();
    void on_westButton_clicked();
    void on_southButton_clicked();
    void on_mapButton_clicked();
    void on_inventDropButton1_clicked();
    void on_inventDropButton2_clicked();
    void on_inventDropButton3_clicked();
    void setDirectionButtonsOn();
    void on_roomTakeButton1_clicked();
    void on_roomTakeButton2_clicked();

private:
    Ui::MainWindow *ui;
    Room *startingRoom, *currentRoom, *nextRoom;
    Inventory *inventory;
    Item *currentItem;
    Item *equippedItem;
    QPixmap roomImage;
    string direction;
    bool b;
    void setDirectionButtons(bool inState);
};

#endif // MAINWINDOW_H

rungame.cpp

#include "ui_mainwindow.h"
#include "rungame.h"
#include "inventory.h"
#include "room.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    w.play();

    return a.exec();
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->imgLabel->updatesEnabled();
    inventory = new Inventory();
    ui->consoleOut->setReadOnly(true);
    setItems();
    createRooms();
    setVisibleItems();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::createRooms()
{
    Room *cell, *solitaryHall, *chrisCell, *showerHall, *canteenHall, *canteen, *guardOffice,
            *visitRoom, *yard, *parkingLot, *runningTrack, *entrance, *shower;

    cell = new Room(1, "your cell", new QPixmap(":/img/img/cell.png"));
        cell->addItem(new Item("Shank", new QPixmap(":/img/img/shank.png"), 1));
        cell->addItem(new Item("Soap", new QPixmap(":/img/img/soap.png"), 2));
    solitaryHall = new Room(2, "the solitary confinement hall", new QPixmap(":/img/img/solitaryhall.png"));
    chrisCell = new Room(3, "Chris' cell", new QPixmap(":/img/img/chriscell.png"));
    showerHall = new Room(4, "the shower hall", new QPixmap(":/img/img/showerhall.png"));
    canteenHall = new Room(5, "the canteen Hall", new QPixmap(":/img/img/canteenhall.png"));
    canteen = new Room(6, "the canteen", new QPixmap(":/img/img/canteen.png"));
        canteen->addItem(new Item("Standard Prison Meal", new QPixmap(":/img/img/meal.png"), 4));
        canteen->addItem(new Item("Fork", new QPixmap(":/img/img/fork.png"), 5));
    guardOffice = new Room(7, "the guards office", new QPixmap(":/img/img/guardoffice.png"));
        guardOffice->addItem(new Item("Guard Uniform", new QPixmap(":/img/img/uniform.png"),6));
    visitRoom = new Room(8, "the visitors Room", new QPixmap(":/img/img/visitroom.png"));
    yard = new Room(9, "the yard", new QPixmap(":/img/img/yard.png"));
    parkingLot = new Room(10, "Parking Lot", new QPixmap(":/img/img/parkinglot.png"));
    runningTrack = new Room(11, "Running Track", new QPixmap(":/img/img/runningTrack.png"));
    entrance = new Room(12, "Prison Entrance", new QPixmap(":/img/img/entrance.png"));
    shower = new Room(13, "Showers", new QPixmap(":/img/img/shower.png"));

    //NORTH, EAST, SOUTH, WEST
    cell->setExits(solitaryHall, NULL, NULL, NULL);
    solitaryHall->setExits(chrisCell, showerHall, cell, NULL);
    chrisCell->setExits(NULL, NULL, solitaryHall, NULL);
    showerHall->setExits(shower, canteenHall, NULL, solitaryHall);
    canteenHall->setExits(canteen, NULL, guardOffice, showerHall);
    canteen->setExits(NULL, NULL, canteenHall, NULL);
    guardOffice->setExits(canteenHall, visitRoom, NULL, NULL);
    visitRoom->setExits(NULL, yard, NULL, guardOffice);
    yard->setExits(runningTrack, parkingLot, entrance, visitRoom);
    shower->setExits(NULL, NULL, showerHall, NULL);

    startingRoom = cell;
    currentRoom = cell;
    lockedRoom = guardOffice;
    roomImage = currentRoom->getImage();
    ui->imgLabel->setPixmap(roomImage);
}

void MainWindow::play()
{
    ui->consoleOut->append("You are sitting at your desk reading a book. The lights go"
                            " out and you hear your cell door unbolt. It starts to creak"
                            " open. Will you leave?");
    ui->consoleOut->append("");
}

void MainWindow::takeItems(int i)
{
    if(inventory->getSize() < 3){
        switch(i){
        case 0: ui->inventSlot1->setVisible(false); ui->roomTakeButton1->setVisible(false); break;
        case 1: ui->inventSlot2->setVisible(false); ui->roomTakeButton2->setVisible(false); break;
        }

        inventory->addItem(currentRoom->getItem(i));
        ui->consoleOut->append(QString::fromStdString("You have taken the: " + currentRoom->getItem(i)->getDescription()));
        currentRoom->deleteItem(i);
        displayInventory();
    }else{
        ui->consoleOut->append("Inventory full. Please drop an item.");
        ui->consoleOut->append("");
    }
    setItems();
}

void MainWindow::dropItems(int i)
{
    if(inventory->getSize() > 0){
        switch(i){
        case 0: ui->inventSlot1->setVisible(true); ui->inventDropButton1->setVisible(true); break;
        case 1: ui->inventSlot2->setVisible(true); ui->inventDropButton2->setVisible(true); break;
        }
        currentRoom->addItem(inventory->getItem(i));
        ui->consoleOut->append(QString::fromStdString("You have dropped the: " + inventory->getItem(i)->getDescription()));
        if(currentRoom->getRoomNum()==13){
            ui->consoleOut->append("You are lucky nobody is around!");
        }
        inventory->deleteItem(i);
        displayInventory();
    }
}

void MainWindow::setVisibleItems()
{
    ui->roomTakeButton1->setVisible(true);
    ui->roomTakeButton2->setVisible(true);
    ui->roomSlot1->setVisible(true);
    ui->roomSlot2->setVisible(true);
    ui->inventSlot1->setVisible(false);
    ui->inventSlot2->setVisible(false);
    ui->inventSlot3->setVisible(false);
    ui->imgLabel->setVisible(true);
}

void MainWindow::display()
{
    setDirectionButtons(true);
    b = true;
    ui->consoleOut->append(QString::fromStdString("Go " + direction));
    ui->consoleOut->append("");
    nextRoom = currentRoom->nextRoom(direction);

    if(currentRoom->getRoomNum()==5){
        if(inventory->hasString("Fork")){
            lockedRoom->setLocked(false);
        }
    }

    if(currentRoom->getRoomNum()==5 && inventory->hasString("Fork")){
        ui->consoleOut->append("You use the fork in your inventory to pick the lock.");
    }

    if(nextRoom == NULL){
        ui->consoleOut->append("You cannot go that way.");
        ui->consoleOut->append("");
    }else if(nextRoom->getLocked()){
        ui->consoleOut->append("This door is locked. Look around for something to help open it, or pick the lock!");
        ui->consoleOut->append("");
    }else{
        currentRoom = nextRoom;
        ui->imgLabel->setPixmap(currentRoom->getImage());
        ui->imgLabel->update();
        ui->consoleOut->append(QString::fromStdString(currentRoom->longDescription()));
        ui->consoleOut->append("");
    }

    if(currentRoom->getRoomNum() == 13 && inventory->hasString("Soap")){
        ui->consoleOut->append("You have Soap in your inventory, be careful not to drop it!");
        ui->consoleOut->append("");
    }

    if(currentRoom->getRoomNum() == 9){
        ui->consoleOut->append("You look around for possible escape methods. ");
        ui->consoleOut->append("North) You can try and jump the chain fence surrounding the running track ");
        ui->consoleOut->append("East) Go into the parking lot and look for a car to hide in ");
        ui->consoleOut->append("South) Walk directly past the guards (Hint: if you have a uniform they might not notice)");
    }

    if(currentRoom->getRoomNum() == 10){
        ui->consoleOut->append("You climb into the back of a delivery truck unnoticed."
                               "The driver starts his engine and drives away. You have escaped!");
        ui->consoleOut->append("");
        ui->imgLabel->setPixmap(QPixmap(":/img/img/parkinglot.png"));
        setVisibleItems();
        setDirectionButtons(false);
    }else if(currentRoom->getRoomNum() == 11){
        ui->consoleOut->append("You make a run for the chainlink fence but a guard dog notices you."
                               "The dog catches up and gets a firm grip of your leg. You're going nowhere."
                               "You have failed to escape.");
        ui->consoleOut->append("");
        ui->imgLabel->setPixmap(QPixmap(":/img/img/runningtrack.png"));
        setVisibleItems();
        setDirectionButtons(false);
    }else if(currentRoom->getRoomNum() == 12){
        if(inventory->hasString("Guards Uniform")){
            ui->consoleOut->append("You walk boldly past the guards at the main entrance."
                                   "They are too busy fixing the power to notice you are a prisoner in their uniform. You have escaped!");
            ui->consoleOut->append("");
            setVisibleItems();
            setDirectionButtons(false);
            ui->imgLabel->setPixmap(QPixmap(":/img/img/escape.png"));
        }else{
            ui->consoleOut->append("You try walking past the guards in your prisoner unifrom."
                                   "You are immediately spotted and caught by the guards. You have failed to escape.");
            ui->imgLabel->setPixmap(QPixmap(":/img/img/prisoner.png"));
            setVisibleItems();
            setDirectionButtons(false);
        }
    }
}

void MainWindow::displayInventory()
{
    int i = 0;
    ui->inventSlot1->setVisible(false);
    ui->inventSlot2->setVisible(false);
    ui->inventSlot3->setVisible(false);
    ui->inventDropButton1->setVisible(false);
    ui->inventDropButton2->setVisible(false);
    ui->inventDropButton3->setVisible(false);

    while(inventory->hasItem(i)){
        switch(i){
        case 0:
            ui->inventSlot1->setPixmap(QPixmap(inventory->getItem(i)->getPic()));
            ui->inventSlot1->setVisible(true);
            ui->inventDropButton1->setVisible(true);
            break;
        case 1:
            ui->inventSlot2->setPixmap(QPixmap(inventory->getItem(i)->getPic()));
            ui->inventSlot2->setVisible(true);
            ui->inventDropButton2->setVisible(true);
            break;
        case 2:
            ui->inventSlot3->setPixmap(QPixmap(inventory->getItem(i)->getPic()));
            ui->inventSlot3->setVisible(true);
            ui->inventDropButton3->setVisible(true);
            break;
        }
        i++;
    }
}

void MainWindow::setItems()
{
    if(currentRoom->hasItem(0)){
        ui->roomSlot1->setPixmap(currentRoom->getItem(0)->getPic());
        ui->roomSlot1->setVisible(true);
        ui->roomTakeButton1->setVisible(true);
    }else{
        ui->roomSlot1->setVisible(false);
        ui->roomTakeButton1->setVisible(false);
    }

    if(currentRoom->hasItem(1)){
        ui->roomSlot2->setPixmap(currentRoom->getItem(1)->getPic());
        ui->roomSlot2->setVisible(true);
        ui->roomTakeButton2->setVisible(true);
    }else{
        ui->roomSlot2->setVisible(false);
        ui->roomTakeButton2->setVisible(false);
    }
}

void MainWindow::on_mapButton_clicked()
{
        int i = currentRoom->getRoomNum();
        switch(i){
            case 1: ui->imgLabel->setPixmap(QPixmap(":/img/img/map1.png"));break;
            case 2: ui->imgLabel->setPixmap(QPixmap(":/img/img/map2.png")); break;
            case 3: ui->imgLabel->setPixmap(QPixmap(":/img/img/map3.png")); break;
            case 4: ui->imgLabel->setPixmap(QPixmap(":/img/img/map4.png")); break;
            case 5: ui->imgLabel->setPixmap(QPixmap(":/img/img/map5.png")); break;
            case 6: ui->imgLabel->setPixmap(QPixmap(":/img/img/map6.png")); break;
            case 7: ui->imgLabel->setPixmap(QPixmap(":/img/img/map7.png")); break;
            case 8: ui->imgLabel->setPixmap(QPixmap(":/img/img/map8.png")); break;
            case 9: ui->imgLabel->setPixmap(QPixmap(":/img/img/map9.png")); break;
            case 10: ui->imgLabel->setPixmap(QPixmap(":/img/img/map10.png")); break;
            case 11: ui->imgLabel->setPixmap(QPixmap(":/img/img/map11.png")); break;
            case 12: ui->imgLabel->setPixmap(QPixmap(":/img/img/map12.png")); break;
            case 13: ui->imgLabel->setPixmap(QPixmap(":/img/img/map13.png")); break;
            }
}

void MainWindow::on_northButton_clicked()
{
    direction = "north";
    display();
}

void MainWindow::on_southButton_clicked()
{
    direction = "south";
    display();
}

void MainWindow::on_eastButton_clicked()
{
    direction = "east";
    display();
}

void MainWindow::on_westButton_clicked()
{
    direction = "west";
    display();
}

void MainWindow::setDirectionButtons(bool inState){
    ui->eastButton->setVisible(inState);
    ui->westButton->setVisible(inState);
    ui->southButton->setVisible(inState);
    ui->northButton->setVisible(inState);

    ui->roomSlot1->setVisible(inState);
    ui->roomSlot2->setVisible(inState);
    ui->roomTakeButton1->setVisible(inState);
    ui->roomTakeButton2->setVisible(inState);


        setItems();


}

void MainWindow::on_roomTakeButton1_clicked()
{
    takeItems(0);
}

void MainWindow::on_roomTakeButton2_clicked()
{
    takeItems(1);
}

void MainWindow::on_inventDropButton1_clicked()
{
    dropItems(0);
}

void MainWindow::on_inventDropButton2_clicked()
{
    dropItems(1);
}

void MainWindow::on_inventDropButton3_clicked()
{
    dropItems(2);
}

void MainWindow::setDirectionButtonsOn()
{
    ui->northButton->setVisible(true);
    ui->eastButton->setVisible(true);
    ui->southButton->setVisible(true);
    ui->westButton->setVisible(true);
}

0 个答案:

没有答案