【问题标题】:Segfault with Qt C++Qt C++ 的段错误
【发布时间】:2015-10-19 09:48:42
【问题描述】:

我的代码因段错误而崩溃,我无法确定错误出在哪里。在将指针作为参数等传递时,我仍在学习指针的方式。这是对此应该很重要的代码。当我运行issueBook() 函数时发生段错误。

IssuedBooks.h

#ifndef ISSUEDBOOKS_H
#define ISSUEDBOOKS_H

#include "ClientList.h"
#include "BookList.h"
#include <QMultiMap>

class IssuedBooks {
public:
    IssuedBooks() {}
    ~IssuedBooks();

    void issueBook(Client*, Book*);
    void returnBook(Client*, Book*);

    ClientList getClients() const;
    BookList getClientBooks(Client*) const;

private:
    QMultiMap<Client*, Book*> issuedBooks;
};

#endif

IssuedBooks.cpp

#include "IssuedBooks.h"
#include <qDebug>

IssuedBooks::~IssuedBooks(){
    qDeleteAll(issuedBooks);
    issuedBooks.clear();
}

void IssuedBooks::issueBook(Client* c, Book* b){
     if(!issuedBooks.contains(c, b)){
        issuedBooks.insert(c, b);
     }
}

void IssuedBooks::returnBook(Client* c, Book* b){
    if(issuedBooks.contains(c, b)){
        issuedBooks.remove(c, b);
    }
}

ClientList IssuedBooks::getClients() const{
    QMapIterator<Client*, Book*> itr(issuedBooks);
    ClientList clients;

    while(itr.hasNext()){
        itr.next();
        clients.addClient(itr.key());
    }

    return clients;
}

BookList IssuedBooks::getClientBooks(Client* c) const{
    QMapIterator<Client*, Book*> itr(issuedBooks);
    BookList books;

    while(itr.hasNext()){
        itr.next();
        if(itr.key() == c){
            books.addBook(itr.value());
        }
    }

    return books;
}

LibraryDriver.cpp

#include "ClientList.h"
#include "BookList.h"
#include "IssuedBooks.h"

#include <QtGui>
#include <QtWidgets>

QTextStream cout(stdout);

int main(int argc, char* argv[]){
    QApplication app(argc, argv);

    BookList bookList;
    ClientList clientList;
    IssuedBooks issueList;

    Book* b = new Book("Nick Corin", "An awesome life.", 59.99);
    bookList.addBook(b);

    Client* c = new Client("Nick Corin", QDate::currentDate());
    clientList.addClient(c);

    issueList.issueBook(c, b);
}

【问题讨论】:

  • 你试过 GDB 来找出它为什么会崩溃吗?
  • 您的issueBook 看起来没问题,所以错误在其他地方。
  • 有人评论询问 app.exec() 但现在我找不到评论?出于某种原因,事实确实如此?我将 app.exe() 添加到我的主要功能的末尾,我所有的问题都消失了吗?知道为什么吗?
  • 好收获!在实际使用QApplication 做任何事情之前,它必须是executed;否则,将不会有任何 Qt 主循环并且没有正确设置 Qt 环境,您所做的一些事情可能会尝试访问;访问不存在的东西会导致段错误。
  • 我从没想过它会产生如此大的不同,因为没有它,程序运行得很好,直到我尝试发行书籍并遇到段错误。十分有趣!我想知道谁评论然后删除它。不管你是谁,你都解决了问题!

标签: c++ qt segmentation-fault


【解决方案1】:

这样的问题在你的编程生活中会经常遇到,所以这里有一个通用的解决方案:

  1. 您应该尝试找出发生段错误的确切位置。我假设您正在使用 GCC/GNU 开发工具链。因此,您要做的第一件事是使用-g 标志编译您的代码,其中包括二进制文件中的调试符号。如果您使用的是 IDE,那么当您选择“调试”作为构建类型时就会发生这种情况。如果您自己打电话给g++,请将-g 添加到g++ 选项中。
  2. 在 gdb 中加载程序,GNU 调试器:gdb --args yourprogram yourprogramarguments
  3. 运行它:(gdb) run&lt;enter&gt;
  4. 等待段错误。
  5. 使用backtrace 命令找出段错误发生的位置。

还有很多其他有用的 gdb 命令可以让您print 变量,或就地修改它们。通常,您想添加breakpoints; help &lt;commandname&gt; 将打印一些帮助。

我为 GNU Radio 开发人员编写了一个更全面的指南,但它也适用于这里:Using GDB to debug

【讨论】:

  • 感谢您,我一直只是手动调试我的代码,而不是使用调试器。我一定会试试的。
【解决方案2】:

初学者最常见的错误是尝试使用尚未创建和初始化的对象。因为变量中的内存指针指向随机地址或null,造成内存访问错误(segfault)。

“在计算中,分段错误(通常缩写为 segfault)或访问冲突是由具有内存保护的硬件引发的故障,通知操作系统 (OS) 有关内存访问冲突”

issueBook() - 函数包含一个强大的候选者作为未初始化的变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    • 2018-04-30
    • 1970-01-01
    相关资源
    最近更新 更多