Problem with deleting QBuffer
-
I have a FileHandler class to handle simple file operations (mainly .csv). I need it to be able to load files both from path (as QFile) and file data (as QBuffer). Here's the crucial part of the class:
#ifndef FILEHANDLER_H #define FILEHANDLER_H #include <QFile> #include <QBuffer> #include <QTextStream> #include <QDir> class FileHandler { public: FileHandler(const QString &path); FileHandler(const QByteArray &data, const QString &path = ""); ~FileHandler(); private: QFile *file = nullptr; QBuffer *buffer = nullptr; QTextStream in; // For writing into a file QTextStream out; // For reading from a file QString path; bool useBuffer = false; }; #endif // FILEHANDLER_H
FileHandler.cpp:
FileHandler::FileHandler(const QString &path) : path(path) , useBuffer(false) { file = new QFile(path); out.setDevice(file); in.setDevice(file); } FileHandler::FileHandler(const QByteArray &data, const QString &path) : path(path) , useBuffer(true) { buffer = new QBuffer(); buffer->setData(data); out.setDevice(buffer); in.setDevice(buffer); } FileHandler::~FileHandler() { delete file; delete buffer; }
In my widget I have the following code:
QString filename = QFileDialog::getOpenFileName(this, "Open File", QDir::homePath(), filter); // Create a temporary handler to check if the file can be opened FileHandler *newHandler = nullptr; if (filename.endsWith(".zip", Qt::CaseInsensitive)) { // Reading .csv from an archive // ... // ... newHandler = new FileHandler(file.readAll(), zipFilename); } else { // If .csv file was selected newHandler = new FileHandler(filename); } if (csvHandler) { csvHandler->close(); csvHandler->clear(); } delete csvHandler; csvHandler = newHandler;
The problem arises only when I'm dealing with a FileHandler constructed with QByteArray, so when FileHandler has QBuffer initialized. The program crashes at the line
delete csvHandler;
with the "is_block_type_valid(header->_block_use)" OR "_crtisvalidheappointer(block)".It DOES NOT happen when a FileHandler is constructed just with filepath. So as I understood, there is something wrong with deleteting QBuffer().
The archive processing works well and there is absolutely nothing wrong with it.
-
@aiphae said in Problem with deleting QBuffer:
Is there a workaround?
I tried this on a release version and it's working well. But what if I want to debug it?
Simple: Link you release build to Qt release libs and your app's debug build to Qt's debug libs.
How did you install Qt?
You should have them. -
Where do you initialize
file
andbuffer
in the ctors? You currently only initialize them in one of the ctors.
Also I don't see a reason why QFile and QBuffer should be created withnew
instead using plain objects in the class. -
@Christian-Ehrlicher they are initialized at declaration time to nullptr.
That said, there's indeed no use for pointers here.
-
@Christian-Ehrlicher said in Problem with deleting QBuffer:
Where do you initialize
file
andbuffer
in the ctors? You currently only initialize them in one of the ctors.
Also I don't see a reason why QFile and QBuffer should be created withnew
instead using plain objects in the class.I want the class to handle EITHER QFile OR QBuffer. Because of this, I decided to make them pointers to save some memory.
UPD: I remade the code so it doesn't use pointers in the FileHandler class. It didn't help. Still the same error.
-
@SGaist said in Problem with deleting QBuffer:
they are initialized at declaration time to nullptr.
Where do you see this?
Now there is also the header... hmm -
@aiphae said in Problem with deleting QBuffer:
. Still the same error.
Please provide some minimal, compilable code and a proper backtrace.
-
@Christian-Ehrlicher said in Problem with deleting QBuffer:
@aiphae said in Problem with deleting QBuffer:
. Still the same error.
Please provide some minimal, compilable code and a proper backtrace.
Maybe this:
FileHandler *csvHandler = nullptr; QVector<QString> files = {"path_1", "path_2"}; for (const auto &path: files) { FileHandler *newHandler = nullptr; newHandler = new FileHandler(QFile(path).readAll); delete csvHandler; csvHandler = newHandler; }
FileHandler.h and FileHandler.cpp are above.
-
This does not crash for me:
int main(int argc, char** argv) { QApplication a(argc, argv); FileHandler* csvHandler = nullptr; QVector<QString> files = { "existing_file1.txt", "existing_file2.txt" }; for (const auto& path : files) { QFile f(path); f.open(QIODevice::ReadOnly); auto newHandler = new FileHandler(f.readAll()); delete csvHandler; csvHandler = newHandler; } delete csvHandler; return 0; }
-
That's interesting. In my code I tried to replace
newHandler = new FileHandler(file.readAll(), zipFilename);
withnewHandler = new FileHandler(file.readAll());
(without specifying a filename). No crash now. So the issue is not in QBuffer.zipFilename is
QString zipFilename = zip.getCurrentFileName();
. I don't understand what's wrong... -
Please try this:
int main(int argc, char** argv) { QApplication a(argc, argv); FileHandler* csvHandler = nullptr; QVector<QString> files = { "existing_file1.txt", "existing_file2.txt" }; for (const auto& path : files) { QFile f(path); f.open(QIODevice::ReadOnly); auto newHandler = new FileHandler(f.readAll(), path); delete csvHandler; csvHandler = newHandler; } delete csvHandler; return 0; }
In this case the error should appear.
-
No crash here and I also don't see a reason why it should crash.
-
As I said before - please post the stacktrace.
-
This?
-
You are most likely mixing debug and release libs - I would guess you link your debug app against Qt release libs. This is not supported on windows due to different msvc runtimes.
-
@Christian-Ehrlicher said in Problem with deleting QBuffer:
You are most likely mixing debug and release libs - I would guess you link your debug app against Qt release libs. This is not supported on windows due to different msvc runtimes.
Is there a workaround?
I tried this on a release version and it's working well. But what if I want to debug it?
-
@aiphae said in Problem with deleting QBuffer:
Is there a workaround?
I tried this on a release version and it's working well. But what if I want to debug it?
Simple: Link you release build to Qt release libs and your app's debug build to Qt's debug libs.
How did you install Qt?
You should have them. -
@Pl45m4 said in Problem with deleting QBuffer:
Simple: Link you release build to Qt release libs and your app's debug build to Qt's debug libs.
Yes. Apparently I was linking external release libraries instead of debug ones. The issue is solved. Thank you!
-