Create QList in constructor then use it in a method
-
Hello,
Is it possible to create a QList in the constructor of a class then use it later in a method of that class? I have a method that prepends data to my QList. If I don't create the QList in that method, my program crashes. However this means that every time I call that method it creates a new QList. I don't want a new QList every time, I just want to add to the same one.
How do I do this?Thanks!
-
Store your list as a member variable.
-
in the .h file I'm assuming? would that look like:
@
public:
QList<QString> m_historyTitle;
@
? -
Yes.
But make it private -- the list should not be accessible to other classes.
-
Ok, do I need to initialize it or anything in the constructor section of the .cpp file?
-
This thread looks like a continuation of http://qt-project.org/forums/viewthread/42329/
What did you learn from Xander84 about list initialization? What's still unclear?
-
That last thread got kinda off topic and into fun stuff like virtual functions, etc. I learned a lot from that thread but it didn't answer my question. I have my QList as a member variable, but whenever I try and do something with it (prepend, etc.) I get a segmentation fault (SEGSEV) and the program crashes. I have not declared the QList in the .cpp file yet and I think this is part of the problem: I am writing data into a QList that doesn't actually exist, that data that I'm writing must be going into an invalid memory address, the OS freaks out and rectifies the problem by crashing my program. Thats my (very) basic understanding of a segmentation fault. I believe that the best way to fix this would be to initialize the QList before I do it, but I'm not sure how thats done. Thus this thread :)
-
[quote author="nicky j" date="1401673288"]I have my QList as a member variable
...
I have not declared the QList in the .cpp file yet and I think this is part of the problem...
I believe that the best way to fix this would be to initialize the QList before I do it, but I'm not sure how thats done. Thus this thread :)[/quote]Thanks for explaining; your question is much clearer now.Ok. When you create an object, the default constructors of all of its (non-pointer) member variables are run first. AFTER THAT, your object's constructor is run.
@
// myobject.h
class MyObject {
public:
MyObject();private:
QList<QString> myList;
};// myobject.cpp
MyObject::MyObject() {
// <-- By the time we reach this line, myList has already been
// initialized as an empty list.// The following line simply adds data to the list that already exists myList.append("Hello!");
}
@In other words, you don't have to do anything special if your list is a member variable. It will automatically be initialized into a valid, empty list. All your methods can read/write the list safely.
If you want, you can call append() (or other functions) in your constructor to add items to the list when your object is created. However, this is not strictly necessary.
[quote]but whenever I try and do something with it (prepend, etc.) I get a segmentation fault (SEGSEV) and the program crashes.[/quote]Given that your list has already initialized, I don't think the segfault has anything to do with your list. I suspect you have bugs in other parts of your code.
Run your program in a debugger and see if you can track down the exact cause of the crash.
But just in case, can you show (paste actual code from your actual program) the ways you try to access your list?
[quote]I am writing data into a QList that doesn’t actually exist, that data that I'm writing must be going into an invalid memory address, the OS freaks out and rectifies the problem by crashing my program. Thats my (very) basic understanding of a segmentation fault.[/quote]If you are indeed writing to uninitialized memory, then yes this is a good description of segfaults. :)
However, from what you've told me, your QList DOES exist. (Even if it's empty, it still exists). So, this is not the cause of your segfault.
-
ok here is where I prepend to the QList:
@
void NBhistoryInterface::addHistoryItem(QString title, QString url)
{
qDebug() << "SLOT: NBhistoryInterface::addHistoryItem(QString title, QString url) STATUS: Called";
qDebug() << "m_historyTitle.prepend() Called";
m_historyTitle.prepend("title");
qDebug() << "m_historyTitle.prepend() Completed";
qDebug() << "SLOT: NBhistoryInterface::addHistoryItem(QString title, QString url) STATUS: Completed";
}
@
by using qdebug's I have narrowed it down to the .prepend() call
here is the crash report:Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000010VM Regions Near 0x10:
-->
__TEXT 000000010d120000-000000010d14e000 [ 184K] r-x/rwx SM=COW /Users/USER/Desktop/*/NovaBrowser_v2.app/Contents/MacOS/NovaBrowser_v2Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 <BUNDLEIDENTIFIER> 0x000000010d137934 QList<QString>::prepend(QString const&) + 20 (qlist.h:546)
1 <BUNDLEIDENTIFIER> 0x000000010d136e67 NBhistoryInterface::addHistoryItem(QString, QString) + 311 (nbhistory.cpp:31)the above crash report leads me to believe there has been a segmentation violation (SIGSEGV). Running the debugger takes me to line 546 of qlist.h where it draws a yellow arrow. It also draws an arrow at the .prepend() call and the methods that call .prepend(). there are no other bugs that it can find. I am 90% sure this is my fault, but could the compiler or my OS be to blame? Thanks for all your help!
-
Hi, before doing the .prepend, could you check the validity of your QList, for example:
@qDebug() << m_historyTitle.size();qDebug() << "m_historyTitle.prepend() Called";
m_historyTitle.prepend("title");
qDebug() << "m_historyTitle.prepend() Completed";
@ -
Ok just tried that. The program crashes when it gets to:
@
qDebug() << m_historyTitle.size();
@This further reinforces my theory that something is wrong with the QList
-
Hi, indeed. the only way for .size() to be able to crash this way, is when the QList variable points into the abyss, for example. the class instance where the QList is declared has been deleted, or new(..) on it has never been called.
To check, you can try by declaring an integer in your class, and set it to something nonzero (like 42 :-) in your constructor.
Then in your qDebug() calls, print out the value of that integer and see if it's still 42. -
In the past, I've seen weird crashes occur in Qt containers like QList/QVector if the compiler is incompatible with the Qt libraries. Example: Crashes will occur if Qt was compiled with GCC 4.4, but the developer compiled his program with GCC 4.7.
Qt Creator is supposed to detect such incompatibilities these days though.
Some questions:
What is your compiler?
What compiler was used to build your copy of Qt?
What happens if you start a new project, create a simple class that only has 1 QList as its member variable, and then you call QList::size() on that variable?
-
looks like I'm using Clang with Qt 5.2.0
Ok I made a new project, and the QList works on it. So Im pretty sure its not a compiler issue... -
[quote author="nicky j" date="1401924295"]looks like I'm using Clang with Qt 5.2.0
Ok I made a new project, and the QList works on it. So Im pretty sure its not a compiler issue...[/quote]That adds weight to my earlier suspicion that there could be bugs in other parts of your code.Unfortunately, memory bugs can be hard to track down, because they don't always cause problems immediately -- they can cause unrelated objects to crash instead.
- What happens if you switch between Debug mode and Release mode?
- What happens if you fully clean your project and build again?
- What happens if you create a new project and copy your old code into it?
-
So the memory bug could be caused by an arbitrary part of my program writing to a certain memory address, then the QList tries to access that memory address? I'm assuming this is a result of how I program. What can I do to improve my programming skill so this doesn't happen in the future? Is there any way I could track down the source of the problem? Is there any way to manually set the memory for the QList?
Switching between Debug and Release doesn't seem to matter; it still crashes.
What exactly is 'cleaning' my project? will cleaning it mess anything up?Thanks!
-
[quote]So the memory bug could be caused by an arbitrary part of my program writing to a certain memory address, then the QList tries to access that memory address? [/quote]Yes, that is one possibility.
[quote]I’m assuming this is a result of how I program.[/quote]It might also be a bug in Qt, or a bug in your compiler, or something else completely. I know this isn't helpful, but the reality is that huge programs will never be bug-free.
[quote]What can I do to improve my programming skill so this doesn’t happen in the future?[/quote]Some good programming habits include:
Remember to initialize all your variables, especially pointers
Minimize your use of low-level memory manipulation functions like memcpy(), memset(), malloc(), etc. and use high-level alternatives like std::copy(), new where possible.
[quote]Is there any way I could track down the source of the problem?[/quote]I'd recommend getting experience in using your debugger and memory checking tools like Valgrind. Taking time to learn these tools will probably help you in all your future projects.
[quote]Is there any way to manually set the memory for the QList?[/quote]Not really. Anyway, that sounds exactly like the sort of low-level memory manipulation that you should avoid.
[quote]What exactly is ‘cleaning’ my project? will cleaning it mess anything up?[/quote]It simply means deleting all the files that got generated when you build your program, and then re-build from scratch. It won't mess up your program, unless you accidentally delete bits of your source code too.