Declaring variables in header file of QT causes program to unexpectedly finish - qt

I have a project "Cybaware_ver1" on QtCreator based on QWidget and everything was working fine. I have a header file with a class containing public and private variables and functions. However, since one day whenever I try to declare a new variable in the header file, even an "int" variable, and run the project, I get
The program has unexpectedly finished.
/home/devdeep/Cybaware_ver1-build-Desktop_Qt_5_0_0_GCC_64bit_SDK-Debug/Cybaware_ver1 exited with code 0
Previously I could add variables in the header file without any problem. Currently, I am able to add new functions, modify UI etc. Just I am unable to add variables to the header file. I have found a temporary solution of declaring these variables as static in the cpp file. However, I would like to find a solution to this.
I have tried re-installing Qt but the problem still persists. I am running it on Ubuntu Linux.
Please let me know if there is a way to fix this. Also, I am not sure what other information I can provide. So please let me know about that.
UPDATE: OK. I used the debugger at it says that the error is a segmentation fault.
It points to the following section of qdebug.h and to the line marked by qt_message_output.
public:
inline QDebug(QIODevice *device) : stream(new Stream(device)) {}
inline QDebug(QString *string) : stream(new Stream(string)) {}
inline QDebug(QtMsgType t) : stream(new Stream(t)) {}
inline QDebug(const QDebug &o):stream(o.stream) { ++stream->ref; }
inline QDebug &operator=(const QDebug &other);
inline ~QDebug() {
if (!--stream->ref) {
if(stream->message_output) {
QT_TRY {
qt_message_output(stream->type,
stream->context,
stream->buffer);
} QT_CATCH(std::bad_alloc&) { /* We're out of memory - give up. */ }
}
delete stream;
}
}
I guess it is a out of memory error. Possible, closing other programs might help?
UPDATE2: Calling "run qmake" did not help. Here is my header file:
#ifndef MAINVIEW_H
#define MAINVIEW_H
#include <QWidget>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QGraphicsLineItem>
#include <QGraphicsEllipseItem>
#include <QGraphicsSimpleTextItem>
#include <list>
#include <QMouseEvent>
#include <QEvent>
#include <QString>
#include <boost/thread.hpp>
#include <qcustomplot.h>
#include <QTimer>
namespace Ui {
class MainView;
}
class MainView : public QWidget
{
Q_OBJECT
public:
int num_missions;
int num_services;
int timer;
int* num_servpermission;
int missionstartx;
//boost::thread pt;
QGraphicsScene mynewscene;
QGraphicsRectItem* myrect;
QGraphicsRectItem** missionline;
QGraphicsLineItem** missionplayline;
QGraphicsRectItem** playrect;
std::list<QGraphicsLineItem**> missionticks;
std::list<QGraphicsEllipseItem**> missionservices;
std::list<QGraphicsSimpleTextItem**> missionservicesno;
std::list<QGraphicsLineItem**>::iterator ti;
std::list<QGraphicsSimpleTextItem**>::iterator ssi;
//std::list<QGraphicsEllipseItem**>::iterator si;
int* missionlength;
int** missionplayxy;
int* missiontickscount;
int* missioniteration;
int missionselected;
int missiontickselected;
int missiontickoffset;
bool isrepeated;
int temp;
QCustomPlot** customPlot;
QTimer dataTimer;
explicit MainView(QWidget *parent = 0);
void playthread();
bool eventFilter(QObject*, QEvent*);
void testfunc();
void clearview();
void test1();
~MainView();
private slots:
void on_startButton_clicked();
void realtimeDataPlot();
void on_pushButton_clicked();
private:
Ui::MainView *ui;
};
#endif // MAINVIEW_H
The program crashes on adding any variable. For example, I added the variable int temp just now and it would crash. Adding anything new makes it crash such as uncommenting the declaration std::list::iterator si;. I take it out and everything works fine.
UPDATE3: My external header file qcustomplot.h is located in the same directory. I am also using boost but that I set up using apt-get. Here is the stack trace:
0 MainView::playthread mainview.cpp 530 0x418fa1
1 boost::_mfi::mf0::operator() mem_fn_template.hpp 49 0x424690
2 boost::_bi::list1 >::operator(), boost::_bi::list0> bind.hpp 253 0x424600
3 boost::_bi::bind_t, boost::_bi::list1 > >::operator() bind_template.hpp 20 0x4245af
4 boost::detail::thread_data, boost::_bi::list1 > > >::run thread.hpp 61 0x42431c
5 thread_proxy /usr/lib/libboost_thread.so.1.46.1 0x7ffff7bcfba9
6 start_thread /lib/x86_64-linux-gnu/libpthread.so.0 0x7ffff6557efc
7 clone /lib/x86_64-linux-gnu/libc.so.6 0x7ffff5af159d
8 ??
The 0th pt in the above trace points to
ui->missionview->invalidateScene()
Here the graphics view gets updated from a function playthread binded to a boost thread. But I am not sure why this would be a problem on adding a variable in the header file as I am not using the variable anywhere in the cpp file.

Go into the project folder and delete the *.pro.user file. Next time you open the project you'll just need to reconfigure it (i.e. choose the appropriate build kit).
I know this is an old thread, but I ran into the same problem myself. Every time I tried to add a variable to my header file it was causing a heap corruption error. I wasn't allocating memory on the heap, or even declaring pointer variables for that matter. It was very frustrating because I didn't know what it was at first. I finally narrowed it down to adding variables to my header file causing the crash. Based on doomguy's experience I knew that it was something persistent in the build folder because he said reinstalling Qt didn't work. I'm glad I read that because I would have been pissed if I reinstalled this behemoth and it still didn't work. Based on prior experience corruption in the .user file can cause issues, and deleting it kinda gives you a clean slate. Moral of the story: If you're getting unusual behavior that seems to point to a problem in the IDE try deleting the .user file before trying more extreme measures.

Not sure if the problem is cause by this, but if the header contains a QObject derived class you should run qmake and after that build your application.
LE: also if this isn't the case, i suggest that you show us a little more code (your code, not Qt code)

Related

writeTextElement() of QXmlStreamWriter crashed when writting the content of a big file

Here is the qt code that crash:
Writing the content of a 130MB binary file will crash, but writing a 2MB binary file will not.
Is there any solution for writeTextElement to write big file content? Thanks
env: qt opensource 4.8.7
Visual Studio 2010
Windows 10
big file: https://1drv.ms/u/s!Ap_EAuwC9QkXijOmXqxp9DEav3gm?e=iha0uI
test project: https://1drv.ms/u/s!Ap_EAuwC9QkXijWzOlpaWmtzOdtz?e=fDpo93
#include <QtCore/QCoreApplication>
#include <QFile>
#include <QXmlStreamWriter>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QByteArray mContentBuffer;
QFile file("C:\\Work\\bigfile.xar");
if(!file.open(QFile::ReadOnly))
{
return -1;
}
mContentBuffer = file.readAll();
file.close();
QFile profile("C:\\Work\\profile.xml");
if(!profile.open(QFile::WriteOnly|QFile::Truncate))
{
return -1;
}
QXmlStreamWriter stream(&profile);
stream.setAutoFormatting(true);
stream.writeStartDocument();
stream.writeStartElement("Profile");
stream.writeTextElement("Content", mContentBuffer.toBase64());
stream.writeEndElement(); // Profile
stream.writeEndDocument();
return a.exec();
}
The minimal reproducible example was a life saver.
Several things seem to be required to solve your issue in a clean way.
Mainly, the file must be read in chunks.To be precise and as mentioned in that other question, in chunks whose size is a multiple of 3 bytes (I have hardcoded 9000 below).You will need to look for the value that gives you the best performance while guaranteeing it never fails yourself.
Instead of writing in the XML in 1 go, I made it so the XML file is being written each chunk at a time.To achieve that, the code creates the node first, then uses the writeCharacters method to write text in it.
Note the if (mContentBuffer.isEmpty()) right before writing. It is indeed specified in Qt Assistant that the read function has no way of reporting errors; returning an empty QByteArray can mean either that no data was currently available for reading, or that an error occurred. Considering the while loop, it can only be an error, so we abort everything.BTW, I think but have not tested that you can just end the document, and the XML stream writer will close everything it needs to have a valid XML.
Just to make it clean, I reordered the lines of codes so that the XML file is opened before the xar file. I also added QtCore/ on every include. Not sure that last point is going to be useful on your real code.
This code implements all the above changes.It should not crash and while you will not be able to test the output on the 130MB file, you should be able to test your code vs mine on the 2MB file you has successfully read from before.
#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
#include <QtCore/QXmlStreamWriter>
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
QFile profile("C:\\Work\\profile.xml");
if (!profile.open(QFile::WriteOnly | QFile::Truncate))
return -1;
QXmlStreamWriter stream(&profile);
stream.setAutoFormatting(true);
stream.writeStartDocument();
stream.writeStartElement("Profile");
stream.writeStartElement("Content");
QFile file("C:\\Work\\bigfile.xar");
if (!file.open(QFile::ReadOnly))
return -1;
while (!file.atEnd()) {
QByteArray mContentBuffer = file.read(9000);
if (mContentBuffer.isEmpty()) {
stream.writeEndDocument();
file.close();
profile.close();
return -1;
}
stream.writeCharacters(mContentBuffer.toBase64());
}
file.close();
stream.writeEndElement(); // </Content>
stream.writeEndElement(); // </Profile>
stream.writeEndDocument();
return a.exec();
}

QPixmap::load() crash - trying to avoid it

I am working on a project, using Qt 4.8.3 for an ARM platform. In my project, I use QGraphicsItems... one of which is a subclass of QGraphicsPixmapItem.
The code was tested with a 32 bit bitmap image - and it crashes.
The crash occurs not just when running on the ARM, but also in QVFB.
QPixmap p;
if (!p.load(filename)) // crashes here
return false;
I have tried to surround this with a try...catch, but it did not help.
I seem unable to step in the Qt code for this version... but the crash occurs inside QImageReader::read(QImage*).
The stack trace:
QImageReader::read(QImage*)
QImageReader::read()
QPixmapData::fromFile(QString const&*, QFlags<QT::ImageConversionFlag>)
QPixmap::load(QString const&, char const*, QFlags<QT::ImageConversionFlag>)
QPixmapItem::loadItemFromFile // mine, the code above
Any other type of image works... and the same 32 bit bitmap loads properly in windows, same Qt version. It fails to load (returning false) in the same Qt version, for Desktop.
I would be happy to exclude this type of file - but I don't know how.
Is there any way to check for the image type without loading the image and avoiding the crash ?
Is there a way to perhaps load the image header only, and verify its type ?
Since you want to exclude 32-bit BMP images, you have to read a BMP header. First two bytes are the characters "BM" and bytes 28, 29 contain bits per pixel.
Here is a small example where we read a file into QByteArray, check its format and load it to QPixmap if OK.
#include <QtCore>
#include <QtGui>
int main(int argc,char** argv)
{
QApplication app(argc,argv);
QFile file("./plot.bmp");
if (!file.open(QIODevice::ReadOnly)) return 1;
QByteArray ba=file.readAll();
if(ba[0]=='B' && ba[1]=='M' && ba[28] == 32) {
qDebug() << "Wrong format!";
return 1;
}
QPixmap pixmap;
pixmap.loadFromData(ba);
qDebug()<<"OK!";
return 0;
}
Or if you don't want to read everything into memory, you can open a file using QFile, ifstream etc, check these bytes and then close it.

Move semantics in Qt without pointers?

I have a Qt project, there I have an Object, which is going to be copied a lot of time. Therefor I would like to add move semantics.
#ifndef OBJECTTOCOPY_H
#define OBJECTTOCOPY_H
#include <QColor>
#include <QString>
#include <QDataStream>
namespace level_1 {
namespace level_2 {
class ObjectToCopy {
public:
explicit ObjectToCopy(const QString& _name = "", const QColor& colorBody = QColor() );
// MOVE
ObjectToCopy(ObjectToCopy && other);
static quint32 _valueInt32;
static quint16 _valueInt16;
QString _name;
QColor _colorBody;
private:
};
}
}
#endif // OBJECTTOCOPY_H
How do I steal the pointers of the member variables, since they are no pointers?
ObjectToCopy::ObjectToCopy (ObjectToCopy&& other)
: _valueInt32( other._valueInt32 )
, _valueInt16( other._valueInt16 )
, _name( other._name )
, _colorBody( other._colorBody )
{
other._valueInt32 = 0;
other._valueInt16 = 0;
other.name.clear();
other._colorBody = QColor();
}
Does that make sense for non-pointers?
Is it ok to reset QString 's like string.clear(); to mark that for the garbage collector?
How could I reset a QColor object?
You can add move semantics of course, but in your case there is no need in this at all. quint32, quint16 are moved by copying. QColor is wrapper around union and has no move constructor (and doesn't need one) and will also be moved by copying. QString is reference counted type in QT. It has move constructor in recent versions of library, but the difference in speed will be minimal (difference between swapping pointer and incrementing reference counter).
You are looking for std::move:
ObjectToCopy::ObjectToCopy (ObjectToCopy&& other)
: _valueInt32( other._valueInt32 )
, _valueInt16( other._valueInt16 )
, _name( std::move(other._name) )
, _colorBody( std::move(other._colorBody) )
{
other._valueInt32 = 0; //probably not necessary
other._valueInt16 = 0; //probably not necessary
//other.name.clear(); //not necessary
//other._colorBody = nullptr; //not necessary
}
It makes sense to move non-pointers. You are in the process of making such an object. Moving integers doesn't help, but doesn't hurt either, so you may as well do it for consistancy. Moving things that don't have a move constructor also works: If no move constructor is available the copy constructor is used (moving is not always better, but not worse either).
The implementation above says "move by copying the ints and moving the name and the _colorBody".
Make sure you do not read from variables you moved from.
It is ok, but not necessary. other is supposed to be a temporary that will get destroyed anyways. (C++ does not have a garbage collector in your sense)
Also once an object is moved from it tends to be in the cleared state like for QString, but that is not always the case.
You cannot really. You can assign a default constructed one like other._colorBody = QColor(); but that just means it sets the color to black. A QColor cannot be empty, it always has some color.
Also read What are move semantics?

atmel studio ifndef compilation error

Hi imy project recognises double definitions of variables that do not exist 2 times. I suppose that some how by changing my code and recompiling it stucks.
LedMatrix7219.cpp.o:(.data.Alphaletter+0x0): multiple definition of `Alphaletter' LedController.cpp.o:(.data.Alphaletter+0x0): first
defined here
LedMatrix7219.cpp.o:In function `loop'
LedController.cpp.o:(.bss.arr+0x0): first defined here
LedMatrix7219.cpp.o:In function `loop'
LedController.cpp.o:(.data.Alphaletter2+0x0): first defined here
collect2.exe*:error: ld returned 1 exit status
I have a class LedController and a header LettersDefinition.h
All the headers start like this:
I am including a struct and an enum from the LetterDefinition.h to the LedController so at the header i need to include the LetterDefinition.h in order to make a certain struck.
#ifndef __LEDCONTROLLER_H__
#define __LEDCONTROLLER_H__
#include <Arduino.h>
#include "LettersDefinition.h"
LetterStruct finalText;
String theText="Test";
void test();
//it does some extra staff
#endif //__LEDCONTROLLER_H__
And the header of the letter definition.
#ifndef LETTERSDEFINITION_H_
#define LETTERSDEFINITION_H_
#include "arduino.h"
#include <avr/pgmspace.h>
struct LetterStruct{
lettersEnum name;
uint8_t size;
uint8_t columnSize[5];
uint8_t data[18];
}Alphaletter;
#endif /* LETTERSDEFINITION_H_ */
And from my main .ide file i call the test function of the Ledcontroller i a get the error you see above. The test fuction just checks the LetterStruct.name variable nothing more.
My .ide is something like:
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include "LedController.h"
LedController controller;
void setup()
{
//irrelevant inits
}
void loop()
{
controller.test();
delay(2000);
}
If i delete the #include "LettersDefinition.h" from the LedController.h this error gives its place to an error that the LetterStruct is not defined in the LedController.h which is normal since i have to add the LettersDefinition.h in order to be defined.
Your problem originates that you "define" variables in header files. This in general will lead to the multiple definition problem and is not standard design.
The model you need to follow is to define once in a source file:
//some.cpp
// this is define
int variableX = 5;
And declare in the header file:
//some.h
// this is declare
extern int variableX;
Every other source file that includes the header just processes the "extern" line, which says roughly "there is an int variableX that will exist in the final program". The compiler runs over every .cpp .c file and creates a module. For the some.cpp that defines the variable, it will create the variableX. All the other .cpp files will just have the extern reference which is a placeholder. The linker will resolve those placeholders when it combines all the modules together.
In your specific case, this means changing:
// .h file should only be externs:
extern LetterStruct finalText;
extern String theText;
// .cpp file contains definitions
LetterStruct finalText;
String theText="Test";

Linking error when including <pcl/io/png_io.h> in more than one file

I wanted to use pcl::io::savePNGFile in two source-files in my code.
As soon as I include the required include in second source-file
# include <pcl/io/png_io.h>
the project doesn't compile.
The error message is:
/usr/include/pcl-1.7/pcl/io/png_io.h:86: multiple definition of `pcl::io::saveRgbPNGFile(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char const*, int, int)'
I'm going to wrap the function in a class in order to include it only once in project. But I think it is not the best way. Am I doing something in a wrong way? Is there a better solution?
Thanks!
EDIT
Finally I've implemented a Q&D solution and wrapped the function (only for normal clouds)
cloudsaver.h
#ifndef CLOUDSAVER_H
#define CLOUDSAVER_H
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <string>
class CloudSaver
{
public:
CloudSaver();
void saveCloudToPNG(const std::string & fileName, const pcl::PointCloud<pcl::PointXYZRGBNormal>& cl );
};
#endif // CLOUDSAVER_H
cloudsaver.cpp
#include "cloudsaver.h"
# include <pcl/io/png_io.h>
CloudSaver::CloudSaver()
{
}
void CloudSaver::saveCloudToPNG(const std::string & fileName, const pcl::PointCloud<pcl::PointXYZRGBNormal>& cl )
{
pcl::io::savePNGFile<pcl::PointXYZRGBNormal>(fileName, cl );
}
But I'm still curious, how to do it properly.
As far as I know, There are some issues related to png_io.h.
I have change the definition of PCL_DEPRECATED in png_io.h file with this definition,and every thing becomes OK.
template <typename T>
PCL_DEPRECATED (void savePNGFile (const std::string& file_name, const pcl::PointCloud<T>& cloud),
"pcl::io::savePNGFile<typename T> (file_name, cloud) is deprecated, please use a new generic "
"function pcl::io::savePNGFile (file_name, cloud, field_name) with \"rgb\" as the field name."
);
look at this link [https://github.com/PointCloudLibrary/pcl/pull/300]
I guess you are using the static version of PCL.
To solve this issue you need to declare those methods as inline.
For example, for PCL 1.7.1, you need to edit this file:
pcl-pcl-1.7.1/io/include/pcl/io/png_io.h
And on these lines, add the keyword inline:
85: inline saveRgbPNGFile(...
96: inline savePNGFile(...
107: inline savePNGFile(...
119: inline savePNGFile(...
173: inline savePNGFile(...
Now rebuild the library, and you should be able to compile without any issues.

Resources