gpt4 book ai didi

如果调用 vector ,C++ vector 段错误会导致崩溃

转载 作者:行者123 更新时间:2023-12-02 02:43:07 26 4
gpt4 key购买 nike

我是个新手,对编码真的没有经验,但是我们在大学接到了一项任务,我遇到了一个我自己无法解决的问题。在一类中, vector 会导致我不明白的问题。经过几个小时的反复试验,我有点厌倦了猜测......所以,我在这里尝试一下并希望得到一些帮助。

该程序应该根据用户可以更改的一些输入变量绘制图表。目前我正在尝试实现图表的绘制。数据的输入和计算有效。

任务的一个方面是我们必须将计算出的数据保存在 vector 中,并将该 vector 作为指针传递给其他函数,例如画家。

现在,问题就出现了。与我传递给 PaintEvent 的 vector m_punkte 的任何交互都会导致程序崩溃。我可以将问题缩小到以下命令: vector ->begin() 或 vector ->end()。在程序尝试执行它们的瞬间,Windows 停止了该程序。

起初我认为 vector 可能以某种方式传递错误,我试图调用一个空 vector 或地址未定义,但即使像 vector -> emty() 这样的命令也会导致崩溃。所以我相信这是一个更普遍的错误,是由框架或类似的东西引起的。

运行调试工具后,它还告诉我错误是由上述命令引起的,并进一步告诉我:

Der Prozess wurde wegen eines Signals vom Betriebssystem angehalten.
Name des Signals : SIGSEGV
Bedeutung : Segmentation fault

我想这是某种内存问题,对吗?

如果有人可以帮助我,我会非常高兴,这样我就可以再次完成实际任务,而不是猜测为什么这个 vector 会被破坏

我还可以告诉的是,我正在使用 Qt Creator,并且该程序正在作为 QtWidget 程序运行(如果有帮助的话)。

Dropbox 链接到该程序的拷贝: https://www.dropbox.com/sh/l5e220lk5y7jx2z/AAAdG7AjHiiKJxOKWT-zrP8ia?dl=0

我希望现在我的问题很清楚,这有助于更多人找到错误的根源。

datenpunkt.h

#ifndef DATENPUNKT_H
#define DATENPUNKT_H

#include <vector>

struct datenpunkt
{
float temperatur;
float widerstand;
float laenge;
};
typedef std::vector<datenpunkt> PunktVektor;

#endif // DATENPUNKT_H

diagrammwidget.h

#ifndef DIAGRAMMWIDGET_H
#define DIAGRAMMWIDGET_H

#include "datenpunkt.h"
#include <QWidget>

namespace Ui {
class DiagrammWidget;
}

class DiagrammWidget : public QWidget
{
Q_OBJECT

public:
explicit DiagrammWidget( QWidget *parent = 0);
~DiagrammWidget();

void setPunkte (PunktVektor *punkte);

void setUntere_temp(int untere_temp);
void setObere_temp(int obere_temp);
void setAufloesung(int aufloesung);

PunktVektor *punkte() const;

protected:
void paintEvent(QPaintEvent *event);

private:
Ui::DiagrammWidget *ui;
PunktVektor *m_punkte;

int m_untere_temp = 0;
int m_obere_temp = 0;
int m_aufloesung = 0;
};

#endif // DIAGRAMMWIDGET_H

对话框.h

#ifndef DIALOG_H
#define DIALOG_H

#include "datenpunkt.h"

#include <string.h>
#include <QDialog>
#include <QString>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
Q_OBJECT

public:
explicit Dialog(QWidget *parent = 0);
~Dialog();

void werteberechnung(PunktVektor *m_PunktListe);

float untere_temp() const;
void setUntere_temp(float untere_temp);

float obere_temp() const;
void setObere_temp(float obere_temp);

int aufloesung() const;
void setAufloesung(int aufloesung);

QString werkstoff() const;
void setWerkstoff(QString werkstoff);

float materialkonstante() const;
void setMaterialkonstante(float materialkonstante);

float bezugswiderstand() const;
void setBezugswiderstand(float bezugswiderstand);

float wiederstand() const;
void setWiederstand(float wiederstand);

float temperatur() const;
void setTemperatur(float temperatur);

private slots:
void on_speichern_clicked();
void on_verwerfen_clicked();
void on_zuruecksetzen_clicked();

private:
Ui::Dialog *ui;
PunktVektor *m_PunktListe;

QString m_werkstoff = "A 34-2/30 (SIEMENS)";
float m_materialkonstante = 3440; // B/ K
float m_bezugswiderstand = 5000; // Rto/ Ohm
float m_untere_temp = 0 + 272.15;
float m_obere_temp = 300 + 272.15;
int m_aufloesung = 10;

float m_RT= 0; // Rt/ Ohm
float m_To = 20 + 272.15;
float m_T = 0; // T/ C°
float m_UD; //Untere Dekadengrenze
float m_OD; //Obere Dekadengrenze

};

#endif // DIALOG_H

diagrammwidget.cpp

#include "diagrammwidget.h"
#include "ui_diagrammwidget.h"
#include "datenpunkt.h"

#include <vector>
#include <QtCore>
#include <QtGui>

DiagrammWidget::DiagrammWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::DiagrammWidget){
ui->setupUi(this);
m_punkte = 0;
}
DiagrammWidget::~DiagrammWidget(){
delete ui;
}
void DiagrammWidget::setPunkte(PunktVektor *punkte){
m_punkte = punkte;
}
void DiagrammWidget::paintEvent(QPaintEvent *event)
{
QPainter myPainter (this);
/*if((m_punkte == 0|| m_punkte->size() == 0)){
myPainter.drawText(100,100,"No Points found!");
return;
}*/
datenpunkt ersterPunkt=*m_punkte->begin();
datenpunkt startPunkt = ersterPunkt;
PunktVektor::iterator it;
for( it = m_punkte->begin()++; it != m_punkte->end(); it++){
datenpunkt p = *it;


myPainter.drawLine(startPunkt.temperatur,startPunkt.laenge,
p.temperatur,p.laenge);
startPunkt = p;
}
}
PunktVektor *DiagrammWidget::punkte() const{
return m_punkte;
}
void DiagrammWidget::setAufloesung(int aufloesung){
m_aufloesung = aufloesung;
}
void DiagrammWidget::setObere_temp(int obere_temp){
m_obere_temp = obere_temp;
}
void DiagrammWidget::setUntere_temp(int untere_temp){
m_untere_temp = untere_temp;
}

对话框.cpp

#include "dialog.h"
#include "ui_dialog.h"
#include "datenpunkt.h"
#include "diagrammwidget.h"

#include <QtCore>
#include <QtGui>
#include <QString>
#include <math.h>

#include <iostream>
using namespace std;

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
m_PunktListe = new PunktVektor;

//Standarteinstellungen
ui->werkstoff->setText("A 34-2/30 (SIEMENS)");
ui->materialkonstante->setValue(3440);
ui->materialkonstante->setSuffix(" K");
ui->bezugswiderstand->setValue(5000);
ui->bezugswiderstand->setSuffix(" Ω");
ui->unteretemperatur->setValue(0);
ui->unteretemperatur->setSuffix(" °C");
ui->oberetemperatur->setValue(300);
ui->oberetemperatur->setSuffix(" °C");
ui->aufloesung->setValue(10);
ui->aufloesung->setSuffix(" Δ°C");

ui->unteretemperatur->setMaximum(ui->oberetemperatur->value());
ui->oberetemperatur->setMinimum(ui->unteretemperatur->value());
ui->unteretemperatur->setSingleStep(ui->aufloesung->value());
ui->oberetemperatur->setSingleStep(ui->aufloesung->value());

werteberechnung(m_PunktListe);

//Diagramm aktualisieren und Anzeigen
DiagrammWidget dg;
dg.setUntere_temp(m_untere_temp);
dg.setObere_temp(m_obere_temp);
dg.setAufloesung(m_aufloesung);
dg.setPunkte(m_PunktListe);
dg.show();
}

Dialog::~Dialog()
{
delete m_PunktListe;
delete ui;
}

void Dialog::werteberechnung(PunktVektor *m_PunktListe)
{
datenpunkt p;
float temp = m_untere_temp;

//Anzahl der zu bestimmenden Datenpunkte
int anzahl = (m_obere_temp-m_untere_temp)/m_aufloesung;

//Bestimmen der Dekadengrenzen UD und OD
m_RT = m_bezugswiderstand * pow(M_E, (m_materialkonstante*
((1/m_obere_temp)-(1/m_To))));
m_UD = (int(log10(m_RT)));
m_RT = m_bezugswiderstand * pow(M_E, (m_materialkonstante*
((1/m_untere_temp)-(1/m_To))));
m_OD = (int(log10(m_RT))+1);

//Füllen des Datenvectors
for (int i = 0; i <= anzahl; i++){
m_RT = m_bezugswiderstand * pow(M_E, (m_materialkonstante*
((1/temp)-(1/m_To))));
p.widerstand = m_RT;
p.temperatur = temp;
float x = log10(m_RT);
if(m_UD != 0){
p.laenge = ((x-m_UD)*5);
}
else
p.laenge = x*5;

m_PunktListe->push_back(p);
temp = temp + m_aufloesung;
}
}

void Dialog::on_speichern_clicked()
{
setWerkstoff(ui->werkstoff->text());
setMaterialkonstante(ui->materialkonstante->value());
setBezugswiderstand(ui->bezugswiderstand->value());
setUntere_temp(ui->unteretemperatur->value()+ 272.15);
setObere_temp(ui->oberetemperatur->value()+ 272.15);
setAufloesung(ui->aufloesung->value());

ui->unteretemperatur->setMaximum(ui->oberetemperatur->value());
ui->oberetemperatur->setMinimum(ui->unteretemperatur->value());
ui->unteretemperatur->setSingleStep(ui->aufloesung->value());
ui->oberetemperatur->setSingleStep(ui->aufloesung->value());

//Berechnung des Datenvectors
werteberechnung(m_PunktListe);

//Diagramm aktualisieren
DiagrammWidget dg;
dg.setUntere_temp(m_untere_temp);
dg.setObere_temp(m_obere_temp);
dg.setAufloesung(m_aufloesung);
dg.setPunkte(m_PunktListe);
dg.show();
}

float Dialog::temperatur() const{
return m_T;
}
void Dialog::setTemperatur(float temperatur){
m_T = temperatur;
}
float Dialog::wiederstand() const{
return m_RT;
}
void Dialog::setWiederstand(float wiederstand){
m_RT = wiederstand;
}
float Dialog::bezugswiderstand() const{
return m_bezugswiderstand;
}
void Dialog::setBezugswiderstand(float bezugswiderstand){
m_bezugswiderstand = bezugswiderstand;
}
float Dialog::materialkonstante() const{
return m_materialkonstante;
}
void Dialog::setMaterialkonstante(float materialkonstante){
m_materialkonstante = materialkonstante;
}
QString Dialog::werkstoff() const{
return m_werkstoff;
}
void Dialog::setWerkstoff(QString werkstoff){
m_werkstoff = werkstoff;
}
int Dialog::aufloesung() const{
return m_aufloesung;
}
void Dialog::setAufloesung(int aufloesung){
m_aufloesung = aufloesung;
}
float Dialog::obere_temp() const{
return m_obere_temp;
}
void Dialog::setObere_temp(float obere_temp){
m_obere_temp = obere_temp;
}
float Dialog::untere_temp() const
{
return m_untere_temp;
}
void Dialog::setUntere_temp(float untere_temp)
{
m_untere_temp = untere_temp;
}
void Dialog::on_verwerfen_clicked()
{
ui->werkstoff->setText(m_werkstoff);
ui->materialkonstante->setValue(m_materialkonstante);
ui->bezugswiderstand->setValue(m_bezugswiderstand);
ui->unteretemperatur->setValue(m_untere_temp);
ui->oberetemperatur->setValue(m_obere_temp);
ui->aufloesung->setValue(m_aufloesung);

ui->unteretemperatur->setMaximum(ui->oberetemperatur->value());
ui->oberetemperatur->setMinimum(ui->unteretemperatur->value());
ui->unteretemperatur->setSingleStep(ui->aufloesung->value());
ui->oberetemperatur->setSingleStep(ui->aufloesung->value());
}

void Dialog::on_zuruecksetzen_clicked()
{
//Standarteinstellungen
ui->werkstoff->setText("A 34-2/30 (SIEMENS)");
ui->materialkonstante->setValue(3440);
ui->bezugswiderstand->setValue(5000);
ui->unteretemperatur->setValue(0);
ui->aufloesung->setValue(10);
ui->oberetemperatur->setValue(300);

setWerkstoff(ui->werkstoff->text());
setMaterialkonstante(ui->materialkonstante->value());
setBezugswiderstand(ui->bezugswiderstand->value());
setUntere_temp(ui->unteretemperatur->value()+ 272.15);
setObere_temp(ui->oberetemperatur->value()+ 272.15);
setAufloesung(ui->aufloesung->value());

ui->unteretemperatur->setMaximum(ui->oberetemperatur->value());
ui->oberetemperatur->setMinimum(ui->unteretemperatur->value());
ui->unteretemperatur->setSingleStep(ui->aufloesung->value());
ui->oberetemperatur->setSingleStep(ui->aufloesung->value());

werteberechnung(m_PunktListe);

}

main.cpp

#include "dialog.h"
#include <QApplication>

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

return a.exec();
}

最佳答案

正如评论中所述,您的示例不是 MCVE 。但猜测,有一些线索:

PunktVektor *m_punkte;         //This is the mentioned vector

datenpunkt test = *m_punkte->begin();    <-            //The programm crashs

除非PunktVector重载operator->(),否则您对 vector 的访问可能应该是

datenpunkt test = m_punkte->begin();    <-            //no dereference (*)


修订:
在更新的示例中,基本问题是取消引用 end() 迭代器,它是一个标记,并不引用元素

    datenpunkt test = *m_punkte->begin(); 
datenpunkt test2 =*m_punkte->end();
*m_punkte->empty();

m_punkte->begin() 返回第一个元素的迭代器(如果有的话; vector 可以为空)。 *( m_punkte->begin() ) 访问迭代器引用的元素。
m_punkte->end() 返回一个标记容器末尾的迭代器。 * (m_punkte->end() ) 未定义。
m_punkte->empty() 返回一个 bool 反射(reflect)容器是否为空。 *( m_punkte->empty() ) 将访问内存位置 01 (这两者都可能非常糟糕。< br/>
修订版 2:
使用容器时,了解如何伤害自己非常重要。特别是,请看这里:

void DiagrammWidget::paintEvent(QPaintEvent *event)
{
QPainter myPainter (this);
/*if((m_punkte == 0|| m_punkte->size() == 0)){
myPainter.drawText(100,100,"No Points found!");
return;
}*/
datenpunkt ersterPunkt=*m_punkte->begin();
datenpunkt startPunkt = ersterPunkt;
PunktVektor::iterator it;
for( it = m_punkte->begin()++; it != m_punkte->end(); it++){
datenpunkt p = *it;

myPainter.drawLine(startPunkt.temperatur,startPunkt.laenge,
p.temperatur,p.laenge);
startPunkt = p;
}
}

如果你要这样做:datenpunkt ersterPunkt=*m_punkte->begin();
那么您必须首先检查容器是否为空。

Container.begin() 返回容器第一个元素的迭代器。如果容器为空,则该迭代器等于Container.end()。取消引用此迭代器是导致程序崩溃的好方法。

尝试像这样重构你的程序:

void DiagrammWidget::paintEvent(QPaintEvent *event)
{
QPainter myPainter (this);
if( m_punkte == nullptr || m_punkte->empty() ){
// myPainter.drawText(100,100,"No Points found!");
return;
}
auto startPunkt = m_punkte->begin();
for( auto it = ++(m_punkte->begin()); it != m_punkte->end(); ++it){
auto const& p = *it;

myPainter.drawLine(startPunkt->temperatur,startPunkt->laenge,
p.temperatur,p.laenge);
startPunkt = it;
}
}

您会发现,在对容器的内容进行假设之前,这可以正确防止空指针或空容器的允许条件。它还按预期使用迭代器,而不是对容器的元素进行不必要的复制。

关于如果调用 vector ,C++ vector 段错误会导致崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50593853/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com