Problem with deleting QBuffer
-
wrote on 14 Nov 2024, 18:47 last edited by
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.
-
@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?
wrote on 15 Nov 2024, 04:46 last edited by@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. -
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.
-
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.wrote on 14 Nov 2024, 19:00 last edited by aiphae@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.
-
@Christian-Ehrlicher they are initialized at declaration time to nullptr.
That said, there's indeed no use for pointers here.
Lifetime Qt Championwrote on 14 Nov 2024, 19:06 last edited by Christian Ehrlicher@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 -
@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.
@aiphae said in Problem with deleting QBuffer:
. Still the same error.
Please provide some minimal, compilable code and a proper backtrace.
-
@aiphae said in Problem with deleting QBuffer:
. Still the same error.
Please provide some minimal, compilable code and a proper backtrace.
wrote on 14 Nov 2024, 19:15 last edited by aiphae@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; }
-
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; }
wrote on 14 Nov 2024, 19:34 last edited by aiphaeThat'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... -
wrote on 14 Nov 2024, 20:00 last edited by aiphae
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.
-
wrote on 14 Nov 2024, 20:13 last edited by
Well it crashes when I'm specifying path and it doesn't when I don't... It's weird.
-
As I said before - please post the stacktrace.
-
As I said before - please post the stacktrace.
wrote on 14 Nov 2024, 20:24 last edited by -
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.
-
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.
wrote on 14 Nov 2024, 20:35 last edited by@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?
-
@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?
wrote on 15 Nov 2024, 04:46 last edited by@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. -
@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.wrote on 15 Nov 2024, 07:53 last edited by@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!
-
1/18