LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-09-2009, 08:34 PM   #1
map250r
Member
 
Registered: Aug 2007
Distribution: Debian Squeeze
Posts: 46

Rep: Reputation: 15
Question c++ vector ::size() nonzero before putting anything in the vector - ?!


I'm a n00b when it comes to c++, sorry if I did something dumb.

I have a vector

Code:
class QOCC_DECLSPEC QoccApplication : public QApplication
{
(...)	
private:
	std::vector<QPluginLoader*> activePlugins;
};
I put stuff in it depending on argv and argc.

Code:
cout<<"argc "<<argc<<endl;
//activePlugins.clear();
if(argc>1){
  doSomeStuff();
  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;
  }
Later:
Code:
cout<<"plugins: " << activePlugins.size() << endl;
for(uint p=0;p<activePlugins.size();p++){
  if(!activePlugins[p]->load()) 
    cout<<"Plugin "<<activePlugins[p]->fileName().toStdString()<<" failed to load. Continuing anyway."<<endl;
}
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
 
Old 01-09-2009, 09:40 PM   #2
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
No; the problem is somewhere else. Please post your backtrace.
ta0kira
 
Old 01-09-2009, 10:16 PM   #3
map250r
Member
 
Registered: Aug 2007
Distribution: Debian Squeeze
Posts: 46

Original Poster
Rep: Reputation: 15
$ 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.
 
Old 01-09-2009, 10:37 PM   #4
map250r
Member
 
Registered: Aug 2007
Distribution: Debian Squeeze
Posts: 46

Original Poster
Rep: Reputation: 15
$ grep -n activePlugins src/qoccapplication.cpp
56: activePlugins.clear();
62: activePlugins.push_back(new QPluginLoader(pList.at(i)));
66: activePlugins.push_back(new QPluginLoader(pluginPath));
75: cout<<"plugins: " << activePlugins.size() << endl;
76: for(uint p=0;p<activePlugins.size();p++){
77: if(!activePlugins[p]->load())
78: cout<<"Plugin "<<activePlugins[p]->fileName().toStdString()<<" failed to load. Continuing anyway."<<endl;


$ grep -n activePlugins inc/qoccapplication.h
56: std::vector<QPluginLoader*> activePlugins;

These are the only lines where activePlugins is used.
 
Old 01-09-2009, 10:48 PM   #5
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
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.
 
Old 01-09-2009, 10:58 PM   #6
map250r
Member
 
Registered: Aug 2007
Distribution: Debian Squeeze
Posts: 46

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by ErV View Post
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;
}
 
Old 01-09-2009, 11:18 PM   #7
map250r
Member
 
Registered: Aug 2007
Distribution: Debian Squeeze
Posts: 46

Original Poster
Rep: Reputation: 15
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;
}
Code:
QoccApplication::QoccApplication(int &argc, char **argv, int _internal ) :
	QApplication (argc, argv, _internal),
	mySplash (NULL)
{
	checkArgs(argc,argv);
}

Last edited by map250r; 01-09-2009 at 11:20 PM. Reason: add code
 
Old 01-09-2009, 11:28 PM   #8
map250r
Member
 
Registered: Aug 2007
Distribution: Debian Squeeze
Posts: 46

Original Poster
Rep: Reputation: 15
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)?

Thanks
map250r
 
Old 01-10-2009, 12:33 AM   #9
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
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()":?
Code:
cout<<"plugins: " << activePlugins.size() << endl;
for(uint p=0;p<activePlugins.size();p++){
  if(!activePlugins[p]->load()) 
    cout<<"Plugin "<<activePlugins[p]->fileName().toStdString()<<" failed to load. Continuing anyway."<<endl;
}
Either something accesses activePlugins, or something overwrites part of memory where instance of your application class is located.

Anyway, right now debugging program is your best bet. To my opinion, at least.

And this:
Quote:
QoccApplication app = new QoccApplication( argc, argv );
won't compile because of missing "*".
 
Old 01-10-2009, 12:43 AM   #10
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
One serious problem in your code:
Quote:
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.
 
Old 01-10-2009, 08:30 AM   #11
map250r
Member
 
Registered: Aug 2007
Distribution: Debian Squeeze
Posts: 46

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by ErV View Post
One serious problem in your code:

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.
 
Old 01-10-2009, 09:01 AM   #12
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
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.
 
Old 01-10-2009, 09:06 AM   #13
map250r
Member
 
Registered: Aug 2007
Distribution: Debian Squeeze
Posts: 46

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by ErV View Post
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()":?
Code:
cout<<"plugins: " << activePlugins.size() << endl;
for(uint p=0;p<activePlugins.size();p++){
  if(!activePlugins[p]->load()) 
    cout<<"Plugin "<<activePlugins[p]->fileName().toStdString()<<" failed to load. Continuing anyway."<<endl;
}
Yes.
Quote:

Either something accesses activePlugins, or something overwrites part of memory where instance of your application class is located.

Anyway, right now debugging program is your best bet. To my opinion, at least.

And this:

won't compile because of missing "*".
So it would be
QoccApplication *app = ...
but this could not make a difference?

gcc didn't like the static_casts, so I just put 0 in place of (QWidget *)this in both places.
 
Old 01-10-2009, 09:28 AM   #14
map250r
Member
 
Registered: Aug 2007
Distribution: Debian Squeeze
Posts: 46

Original Poster
Rep: Reputation: 15
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?

Thanks for the help.
 
Old 01-10-2009, 09:33 AM   #15
map250r
Member
 
Registered: Aug 2007
Distribution: Debian Squeeze
Posts: 46

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by johnsfine View Post
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...

Thanks
map250r
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
C++ vector or string size sefaklc Programming 20 08-02-2008 12:14 AM
LXer: Vector Linux 5.9-Pseudo64-0.1 -- Finally, 64-bit Vector LXer Syndicated Linux News 0 09-12-2007 01:20 PM
LXer: This is Vector. This is Vector on Fluxbox. LXer Syndicated Linux News 0 08-30-2007 11:20 AM
can i modify int 80 vector to a user-defined vector qqrilxk Linux - Security 1 03-03-2005 08:46 PM
Miseries at install from HDD&floppies, with vector ISO& how to boot with vector linux prctom VectorLinux 9 06-29-2004 05:27 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:05 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration