开发者

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;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜