c++ vector ::size() nonzero before putting anything in the vector - ?!
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I get a segmentation fault if I run the program with no arguments:
Code:
argc 1
plugins: 1013170
Program received signal SIGSEGV, Segmentation fault.
According to GDB, the problem occurs when I try to load a plugin.
I can fix this by uncommenting the line in green - but I thought that C++ initialized variables automatically.
Am I expected to clear the vector, or not?
I'm using Debian Lenny on AMD64, and GCC 4.2.2.
Thanks
Last edited by map250r; 01-09-2009 at 08:35 PM.
Reason: clarify
$ gdb ./debug/qOcc
GNU gdb 6.7.1-debian
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu"...
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) r
Starting program: /home/mark/projects/occ-other/qtOccHarness-0.1/debug/qOcc
[Thread debugging using libthread_db enabled]
[New Thread 0x7f83977147c0 (LWP 11639)]
argc 1
plugins: 1013170
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7f83977147c0 (LWP 11639)]
0x000000000041677a in QoccApplication::registerPlugins (this=0x7fff9f86c8c0)
at src/qoccapplication.cpp:77
warning: Source file is more recent than executable.
77 if(!activePlugins[p]->load())
(gdb) bt
#0 0x000000000041677a in QoccApplication::registerPlugins (this=0x7fff9f86c8c0)
at src/qoccapplication.cpp:77
#1 0x00000000004160e0 in main (argc=1, argv=0x7fff9f86c9d8) at src/main.cpp:37
(gdb)
The source file warning is because I uncommented the line that clears the vector.
There is not enough information to help you.
I think problem might be located at line 62 ("activePlugins.push_back(new QPluginLoader(pList.at(i)));") which isn't provided. Either give full function listings, or check size of activePlugins (print it to stdout/stderr) before and after parsing argc/argv, and especially around mysterious "doSomeStuff()" call.
There is not enough information to help you.
I think problem might be located at line 62 ("activePlugins.push_back(new QPluginLoader(pList.at(i)));") which isn't provided. Either give full function listings, or check size of activePlugins (print it to stdout/stderr) before and after parsing argc/argv, and especially around mysterious "doSomeStuff()" call.
If I run the program without arguments, activePlugins.push_back() shouldn't get called. So size should be 0, correct? Writing "doSomeStuff()" was just my attempt to provide a shorter piece of code, yet show that some things were left out.
Code:
void QoccApplication::checkArgs(int &argc, char **argv){
cout<<"argc "<<argc<<endl;
//activePlugins.clear();
if(argc>1){
if (!strcmp(argv[2],"ask")){
//arg is ask - so ask.
QStringList pList = QFileDialog::getOpenFileNames((QWidget *)this,"Choose a plugin. Ctrl for multiple.", QDir::currentPath(),"Plugins (*.qop.so)");
for(int i = 0;i<pList.size();i++)
activePlugins.push_back(new QPluginLoader(pList.at(i)));
} else for(int c = 1;c<argc;c++){
QString pluginPath = QDir::currentPath() + "/" + argv[c];
if (QFile::exists(pluginPath))
activePlugins.push_back(new QPluginLoader(pluginPath));
else cout<<"Error: Plugin "<<pluginPath.toStdString()<<" not found. Skipping."<<endl;
}
}
//numPlugins=0;
}
OK, something wierd is going on. I made it print the vector size when it prints argc. At that point it is zero. Because argc is 1, everything in the if() gets skipped.
argc 1 plugins: 0
plugins: 1013170
checkArgs() is called when the program loads. The function where the seg fault occurs, registerPlugins(), is called after the gui has initialized.
Code:
int main(int argc, char *argv[])
{
QoccApplication app( argc, argv ); //checkArgs is called from here
QoccHarnessWindow *window = new QoccHarnessWindow();
window->show();
app.registerPlugins();
int retval = app.exec();
return retval;
}
OK, shows how much of a newb I am, would it make a difference if I changed
Code:
QoccApplication app( argc, argv );
to something like
Code:
QoccApplication app = new QoccApplication( argc, argv );
What I'm wondering is, will it not stay in memory without the keyword "new"?
I'm modifying an old version of someone else's code (http://qtocc.sourceforge.net/). What are the implications of using the second line in place of the first (if that's not too difficult to explain)?
You should try to debug your program with "gdb"(or another debugger), in step-by-step mode, but you'll have to find/read some tutorials about debugging if you are a newbie. advancedlinuxprogramming.com should explain debugging on linux. If haven't done this before, then you'll need some time to get used to gdb.
Right now I don't see what causes this problem. Is this a complete implementation of "registerPlugins()":?
void QoccApplication::checkArgs(int &argc, char **argv){
....
QStringList pList = QFileDialog::getOpenFileNames((QWidget *)this,"Choose a plugin. Ctrl for multiple.", QDir::currentPath(),"Plugins (*.qop.so)");
....
You must not cast QoccApplication* into QWidget*. Don't do this in Qt. QWidget is not a base classe of QoccApplication. Using this pointer might corrupt internal state of QoccApplication object. When you need to cast pointer to one class into pointer to other, use static_cast or dynamic_cast instead. At least in those cases you'll get segfault immediately, so you'll notice the problem right now, instead of getting hard to catch bugs later (might take a week to find something like this).
Doing something similar in other places might be cause of your problem.
You must not cast QoccApplication* into QWidget*. Don't do this in Qt. QWidget is not a base classe of QoccApplication. Using this pointer might corrupt internal state of QoccApplication object. When you need to cast pointer to one class into pointer to other, use static_cast or dynamic_cast instead. At least in those cases you'll get segfault immediately, so you'll notice the problem right now, instead of getting hard to catch bugs later (might take a week to find something like this).
Doing something similar in other places might be cause of your problem.
I only do that twice, and neither piece of code is executed before the segfault. The first cast would only happen if argc is not < 1. The second cast never happens because the function (unRegisterPlugins) is not used anywhere.
I have changed to a static cast, but have yet to compile it.
I don't see the error in any of the code you have posted. What you have described hints at a couple possibilities:
1) The QoccApplication destructor is being called on that object and then you continue to use it, causing the seg fault.
2) The seg fault occurs on a different QoccApplication object.
I couldn't tell if anyone answered your original question unambiguously: You are not required to clear the vector. The constructor for the vector clears it and that constructor is called automatically by the constructor for the containing class even if you don't do that explicitly.
I don't really trust gdb in C++ code, so I would use some cout's to investigate the two ideas I mentioned above. You could do the same with breakpoints more quickly if you trust gdb.
In each of the following places show the value of the current QoccApplication pointer ("this" if you are in a method of that class):
QoccApplication constructor
QoccApplication destructor
The place you were checking argc
The place right before the seg fault.
Those should tell you whether it is all the same object or not and it should tell you if the construction or destruction is occurring out of correct sequence.
You should try to debug your program with "gdb"(or another debugger), in step-by-step mode, but you'll have to find/read some tutorials about debugging if you are a newbie. advancedlinuxprogramming.com should explain debugging on linux. If haven't done this before, then you'll need some time to get used to gdb.
Right now I don't see what causes this problem. Is this a complete implementation of "registerPlugins()":?
Ugggh. I'm leaning towards stale .o files causing this.
I tried to debug from kDevelop. It complained that it couldn't find the program, even after a clean build (errrm, "Rebuild Project"). I selected "debug" in QMake Manager and did a clean build. Tried to debug again, and now the program works.
I imported this project into kdevelop, and kdevelop had trouble parsing the .pro file IIRC. I get .o files all over the place, and now I'm wondering if it's been using a stale one. I have been using "Rebuild Project" instead of "Build Project", thinking that rebuild would delete any .o files, but now I wonder if it might only delete .o files where it expected to find them, then for some reason link against one elsewhere. How likely is that?
I don't see the error in any of the code you have posted. What you have described hints at a couple possibilities:
1) The QoccApplication destructor is being called on that object and then you continue to use it, causing the seg fault.
2) The seg fault occurs on a different QoccApplication object.
I couldn't tell if anyone answered your original question unambiguously: You are not required to clear the vector. The constructor for the vector clears it and that constructor is called automatically by the constructor for the containing class even if you don't do that explicitly.
I don't really trust gdb in C++ code, so I would use some cout's to investigate the two ideas I mentioned above. You could do the same with breakpoints more quickly if you trust gdb.
In each of the following places show the value of the current QoccApplication pointer ("this" if you are in a method of that class):
QoccApplication constructor
QoccApplication destructor
The place you were checking argc
The place right before the seg fault.
Those should tell you whether it is all the same object or not and it should tell you if the construction or destruction is occurring out of correct sequence.
I printed "this" at the last two points, and they were the same. The problem has dissappeared, as I mentioned in another post. Hopefully it stays dissappeared. :-)
I still don't get why the problem went way earlier, when I had the clear() line uncommented...
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.