PDA

View Full Version : [solved] Segmentation fault - I don't understand why



Garry26
29th September 2010, 23:28
Hello,

I have written a short function to build a simple directory tree into a QStringList. Sometimes the function completes successfully but most of the times it does not, and fails with a "Segmentation fault" error on line 32.

I am modifying the QStringList while iterating through it, but I think it still looks like it should be okay to do this.


//
// Sample usage at the bottom
//

#include <QDir>
#include <QStringBuilder>

void getDirectoryTree(const QDir& directory, QStringList& tree)
{
tree.clear();
tree.push_back("/");

for (QStringList::iterator it = tree.begin(); it != tree.end(); ++it)
{
// Real directory or file path
QString currentFilePath(directory.path() % *it);

// If this isn't a directory, don't try to look into it.
if (!QFileInfo(currentFilePath).isDir())
{
continue;
}

// Real directory
QDir currentDirectory(currentFilePath);

// Get list of files in this directory and iterate through them
QStringList subFiles = currentDirectory.entryList(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
for (QStringList::iterator itSubFile = subFiles.begin(); itSubFile != subFiles.end(); ++itSubFile)
{
// Holds the relative path of this file/directory
QString subFileRelativePath(*it); // <---------- Segmentation fault occurs
subFileRelativePath += *itSubFile;
// Add a directory separator if this is a directory
if (currentDirectory.cd(*itSubFile))
{
currentDirectory.cdUp();
subFileRelativePath += "/";
}

// Add it to the directory tree
tree.push_back(subFileRelativePath);
}
}
}

//
// Sample usage
//

#include <QMessageBox>

void MainWindow::on_pushButton_clicked()
{
QStringList tree;
getDirectoryTree(QDir("D:\\New folder (2)"), tree);
QMessageBox::information(this, "", tree.join("\n"));
}
If you use Qt Creator, just create a new Qt GUI application, drop a button on the form, add a "clicked()" slot and then it's pretty much just pasting my code into mainwindow.cpp.

I am feeling pretty frustrated because I don't understand why this problem occurs. :confused:
While I could go a different way (recursive function or use arrays), I feel that this should work one way or another.

Any help on this and other suggestions for improvement, is much appreciated!

Thanks in advance!

Regards,
Garry

SixDegrees
29th September 2010, 23:38
Iterators become invalid when they object they iterate over is modified. While what you're trying to do here may work in some cases, it will quite likely fail in others, as you've discovered.

Try building a separate QStringList that gets generated through a recursive function call.

Garry26
30th September 2010, 00:02
Thank you, SixDegrees. I was thinking the same but still sort of assumed it should have worked differently. I'll give it a try with a simple recursive function call and update this post afterwards. I'm pretty sure it will work, I just hoped I could avoid it in a simple and sensible manner.

Edit: Found QDirIterator. Makes it much easier to walk through a directory tree! :)