gbonnema
6th January 2015, 11:56
I have a problem with a program I am working on where serializing a QHash gets me a segfault. As the project is too much code to show, I isolated what created the problem and could reproduce the segfault.
Does anyone have a clue what I am doing wrong here? I am sorry that it's a lot of code, it's not very complex though (I am newbie at both C++ and Qt).
It runs until the statement "data2 >> datum2". After that I get a segfault.
0000 Program start.
0001 Datum1 written to buffer.
0002 Buffer about to open for reading.
0003 data2 about to initialize with buffer.
0004 data2 initialized with buffer.
0005 data2 about to read buffer into datum2.
Segmentation fault (core dumped)
This code is main.cpp.
#include <memory>
#include <iostream>
#include <exception>
#include <QCoreApplication>
#include <QBuffer>
#include <QIODevice>
#include "datum.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout << "0000 Program start." << std::endl;
std::shared_ptr<Datum> datum = std::make_shared<Datum>();
std::shared_ptr<Thing> thing = std::make_shared<Thing>();
thing->name("name of thing");
datum->add(thing);
QBuffer buffer;
// Write datum into buffer
buffer.open(QIODevice::WriteOnly);
QDataStream data(&buffer);
data << datum;
buffer.close();
std::cout << "0001 Datum1 written to buffer." << std::endl;
// Read datum2 from buffer
std::shared_ptr<Datum> datum2;
std::cout << "0002 Buffer about to open for reading." << std::endl;
buffer.open(QIODevice::ReadOnly);
std::cout << "0003 data2 about to initialize with buffer." << std::endl;
QDataStream data2(&buffer);
std::cout << "0004 data2 initialized with buffer." << std::endl;
try {
std::cout << "0005 data2 about to read buffer into datum2." << std::endl;
data2 >> datum2;
std::cout << "0006 data2 just read buffer into datum2." << std::endl;
buffer.close();
std::cout << "0007 Datum2 read from buffer." << std::endl;
} catch (std::exception &e) {
std::cout << "0008 Error during read from buffer: " << e.what() << std::endl;
}
std::cout << "0009 Program end." << std::endl;
return a.exec();
}
Following the datum.h and datum.cpp files.
#ifndef DATUM_H
#define DATUM_H
#include <iostream>
#include <memory>
#include <QDataStream>
#include <QHash>
class Thing {
friend QDataStream &operator<< (QDataStream &ds, std::shared_ptr<const Thing>);
friend QDataStream &operator>> (QDataStream &ds, std::shared_ptr<Thing>);
public:
QString name() const { return m_name; }
void name(const QString name) { m_name = name; }
private:
QString m_name;
};
class Datum
{
friend QDataStream &operator<< (QDataStream &ds, std::shared_ptr<const Datum>);
friend QDataStream &operator>> (QDataStream &ds, std::shared_ptr<Datum>);
public:
Datum();
~Datum();
void add(std::shared_ptr<Thing>);
private:
QHash<QString, std::shared_ptr<Thing>> m_list;
};
QDataStream &operator<< (QDataStream &ds, std::shared_ptr<const Thing>);
QDataStream &operator>> (QDataStream &ds, std::shared_ptr<Thing>);
QDataStream &operator<< (QDataStream &ds, std::shared_ptr<const Datum>);
QDataStream &operator>> (QDataStream &ds, std::shared_ptr<Datum>);
#endif // DATUM_H
#include "datum.h"
Datum::Datum()
{
}
Datum::~Datum()
{
}
void Datum::add(std::shared_ptr<Thing> thing) {
m_list.insert(thing->name(), thing);
}
QDataStream &operator<< (QDataStream &ds, std::shared_ptr<const Thing> thing) {
ds << thing->m_name;
return ds;
}
QDataStream &operator>> (QDataStream &ds, std::shared_ptr<Thing> thing) {
ds >> thing->m_name;
return ds;
}
QDataStream &operator<< (QDataStream &ds, std::shared_ptr<const Datum> datum) {
ds << datum->m_list;
return ds;
}
QDataStream &operator>> (QDataStream &ds, std::shared_ptr<Datum> datum) {
ds >> datum->m_list;
return ds;
}
Does anyone have a clue what I am doing wrong here? I am sorry that it's a lot of code, it's not very complex though (I am newbie at both C++ and Qt).
It runs until the statement "data2 >> datum2". After that I get a segfault.
0000 Program start.
0001 Datum1 written to buffer.
0002 Buffer about to open for reading.
0003 data2 about to initialize with buffer.
0004 data2 initialized with buffer.
0005 data2 about to read buffer into datum2.
Segmentation fault (core dumped)
This code is main.cpp.
#include <memory>
#include <iostream>
#include <exception>
#include <QCoreApplication>
#include <QBuffer>
#include <QIODevice>
#include "datum.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout << "0000 Program start." << std::endl;
std::shared_ptr<Datum> datum = std::make_shared<Datum>();
std::shared_ptr<Thing> thing = std::make_shared<Thing>();
thing->name("name of thing");
datum->add(thing);
QBuffer buffer;
// Write datum into buffer
buffer.open(QIODevice::WriteOnly);
QDataStream data(&buffer);
data << datum;
buffer.close();
std::cout << "0001 Datum1 written to buffer." << std::endl;
// Read datum2 from buffer
std::shared_ptr<Datum> datum2;
std::cout << "0002 Buffer about to open for reading." << std::endl;
buffer.open(QIODevice::ReadOnly);
std::cout << "0003 data2 about to initialize with buffer." << std::endl;
QDataStream data2(&buffer);
std::cout << "0004 data2 initialized with buffer." << std::endl;
try {
std::cout << "0005 data2 about to read buffer into datum2." << std::endl;
data2 >> datum2;
std::cout << "0006 data2 just read buffer into datum2." << std::endl;
buffer.close();
std::cout << "0007 Datum2 read from buffer." << std::endl;
} catch (std::exception &e) {
std::cout << "0008 Error during read from buffer: " << e.what() << std::endl;
}
std::cout << "0009 Program end." << std::endl;
return a.exec();
}
Following the datum.h and datum.cpp files.
#ifndef DATUM_H
#define DATUM_H
#include <iostream>
#include <memory>
#include <QDataStream>
#include <QHash>
class Thing {
friend QDataStream &operator<< (QDataStream &ds, std::shared_ptr<const Thing>);
friend QDataStream &operator>> (QDataStream &ds, std::shared_ptr<Thing>);
public:
QString name() const { return m_name; }
void name(const QString name) { m_name = name; }
private:
QString m_name;
};
class Datum
{
friend QDataStream &operator<< (QDataStream &ds, std::shared_ptr<const Datum>);
friend QDataStream &operator>> (QDataStream &ds, std::shared_ptr<Datum>);
public:
Datum();
~Datum();
void add(std::shared_ptr<Thing>);
private:
QHash<QString, std::shared_ptr<Thing>> m_list;
};
QDataStream &operator<< (QDataStream &ds, std::shared_ptr<const Thing>);
QDataStream &operator>> (QDataStream &ds, std::shared_ptr<Thing>);
QDataStream &operator<< (QDataStream &ds, std::shared_ptr<const Datum>);
QDataStream &operator>> (QDataStream &ds, std::shared_ptr<Datum>);
#endif // DATUM_H
#include "datum.h"
Datum::Datum()
{
}
Datum::~Datum()
{
}
void Datum::add(std::shared_ptr<Thing> thing) {
m_list.insert(thing->name(), thing);
}
QDataStream &operator<< (QDataStream &ds, std::shared_ptr<const Thing> thing) {
ds << thing->m_name;
return ds;
}
QDataStream &operator>> (QDataStream &ds, std::shared_ptr<Thing> thing) {
ds >> thing->m_name;
return ds;
}
QDataStream &operator<< (QDataStream &ds, std::shared_ptr<const Datum> datum) {
ds << datum->m_list;
return ds;
}
QDataStream &operator>> (QDataStream &ds, std::shared_ptr<Datum> datum) {
ds >> datum->m_list;
return ds;
}