Segmentation fault when trying to receive pointer value in Qt
I'm quite new to Qt and c++ but not new to programming at all. I am having trouble using pointers in my program. In my header file I have got the following private variable pointer assignment:
private:
QString *currentFile;
In my program I have got a function that starts by copying the value of the currentFile pointer to another QString variable:
QString fileName = *currentFile;
However this immediately gives me segmentation fault when debugging. I have absolutely no idea what I am doing wrong.
The program runs just fine until I call the function that tries to get the vlue of the pointer. I figured it might be becuase the pointer was empty so I tried adding the following code to my construct开发者_JS百科er:
*currentFile = QString::null;
To assign a null
value to the pointer value, however this just gave me the segmentation fault as soon as the constructer was called.
Hope someone can help.
Thanks
EDIT
more code:
notepad.h:
class Notepad : public QMainWindow
{
Q_OBJECT
public:
Notepad();
private slots:
void open();
void save();
void saveAs();
void quit();
private:
QTextEdit *textEdit;
QString *currentFile;
QString *currentContents;
};
the function creating the error (void save()) in notepad.cpp:
void Notepad::save(){
QString fileName = *currentFile;
if(fileName != "")
{
QFile file(fileName);
if(!file.open(QIODevice::WriteOnly))
{
QMessageBox::critical(this, tr("Error"), tr("Could not write to file"));
return;
}
else
{
QTextStream stream(&file);
QString editorContent = textEdit->toPlainText();
currentContents = &editorContent;
stream << editorContent;
stream.flush();
file.close();
}
}
else
saveAs();
}
This is most probably due to the fact, that you never allocated any storage for the string. The pointer just stores a memory address and if its value is initialized to 0 (or even worse to nothing and contains a completely undefined address), then it doesn't point to a valid string object and trying to use the memory it points to as a string object results in undefined behaviour (in your case a segfault).
So you first need to allocate memory for a string and construct the string using (probably in the surrounding object's constructor):
currentFile = new QString;
and later (when not needed anymore, e.g. in the surrounding object's destructor):
delete currentFile;
But as said in the comments, I really doubt that you need a pointer member. Why not just use a QString
object as member. Or if you really need pointers, rather use some smart pointer (like auto_ptr
or the new C++11 unique_ptr
or shared_ptr
).
With QObject
derived types (widgets and the like) it's a different story and you rather should use pointers for them (and Qt handles deallocation for you, if used properly). But QString
is (like strings usually are) a rather value-like type (similar to the builtin types) and in most cases doesn't have to be allocated dynamically.
In both cases:
QString fileName = *currentFile;
*currentFile = QString::null;
you dereference an unitialized pointer.
The 2nd assignment doesn't initialize pointer to NULL; what it does is: dereference currentFile pointer first and destroy the object it points to, and replace it with QString::null object.
QString::null is a special structure used by Qt to indicate uninitialized strings, but don't confuse it with NULL pointer.
You should initialize your pointer like this:
currentFile = new QString();
There's no reason to use pointers at all in the code you provided. So, try this instead (from the code before you provided your edit)
private:
QString currentFile;
QString fileName = currentFile;
currentFile = QString::null;
If currentFile is null then of course de-referencing it is going to crash. Setting it to QString::null does not give you an empty string. It gives you a null pointer. What you want is something like this: currentFile = "";
Cat Plus also has a good point. You don't need a pointer in the first place (for what you've shown us).
Put this in the constructor:
currentFile = new QString();
and don't forget to delete it (for example in the destructor.):
delete currentFile;
精彩评论