My sub-sub-class is not being included
-
Sorry I thought I wrote it down, I'm working on Linux Ubuntu 11.04 32bit, QtCreator 2.0.1, Qt 4.7.0.
I don't think I'm using any toolchain, unless QtCreator does it by default. No optimizations either, again unless Qtcreator does it.
I'm working on an example but I got into one, of the several, issue that need to be fixed first. This should be very basic stuff but it seems I'm doing something wrong and can't see it:
My ToolsClass uses two arrays declared as pointers to float and I'm deleting them as I used to but the application crashes when trying to free those pointers. Here is my class declaration:
@
class BADtools{
private:
int sFieldX, sFieldY;
bool hasParameters;
public:
int sMax;
float *rangeIx;
float *rangeIy;
BADtools();
BADtools( int minx, int maxX, int minY=0, int maxY=1 );
virtual ~BADtools();
};
@
and here is the definition:
@
#include <iostream>#include "badTools.h"
using namespace BAD;
using namespace std;
//______________________________________________
// constructors
//______________________________________________
BADtools::BADtools(){
cout << "NoArgs badTools: initialized!" << endl;
hasParameters = false;
}
BADtools::BADtools( int xMin, int xMax, int yMin, int yMax ){
hasParameters = true;
sFieldX = xMax - xMin;
sFieldY = yMax - yMin;
if(sFieldX > sFieldY) sMax = sFieldX;
else sMax = sFieldY;
// IPP: memory allocation
rangeIx = new float[sFieldX];
rangeIy = new float[sFieldY];
// Asymmetric ranges: for building inputs
for( int i=xMin; i<=xMax; i++ )
rangeIx[i-xMin] = (float)i;
for( int j=yMin; j<=yMax; j++)
rangeIy[j-yMin] = (float)j;
cout << "4Args badTools: initialized!" << endl;
}//______________________________________________
// destructor
//______________________________________________
BADtools::~BADtools(){
cout << "badTools... ";
if(hasParameters){
delete []rangeIx;
delete []rangeIy;
cout << "data destroyed!" << endl;
}else
cout << "Nothing to destroy!" << endl;
}
@
I'm not that of an expert programming so please forgive me if what I'm missing is too basic. But wherever I've seen that is the way you dynamically save memory and then that's how you free that memory, isn't it?
I created a simple GUI to know the sMax variable everytime the user clicks a button... but that's not the important part. I also created a simple main file to test this:
@
#include <iostream>#include "badTools.h"
using namespace std;
int main(int argc, char *argv[]){
BAD::BADtools *tools = new BAD::BADtools(-5,8);
int sMax = tools->sMax;
cout << "Max size: " << sMax << endl;
delete tools;cout << "bye without Qt!" << endl;
return 0;
}
@
What am i doing wrong? -
The program works for me without errors or crashes (GCC 4.2 on Mac OS X, which should be comparable to Ubuntu 10.x)
Your right with your couple of
@new [] together with delete []@
And I see no dangling pointers or the like.
Just another hint: In your parameter less constructor set the two array pointers to null:
@
rangeIx = 0;
rangeIy = 0;
@This prevents access to dangling pointers from outside your class. And it saves you the if in the destructor, as deleting a null pointer is guaranteed to do nothing:
@
BADtools::~BADtools(){
delete []rangeIx;
delete []rangeIy;
}
@BTW: I don't know if it is valid to do a
@
float *fPtr = new float[0];
@You might want to check this.
-
The 2. constructor has some issues too,:
You call:
@
new BADtools(-5,8);
@this leads to:
@
BADtools::BADtools( int xMin=-5, int xMax=8, int yMin=0, int yMax=1 )
{
sFieldX = xMax - xMin; // 13
sFieldY = yMax - yMin;// 1
sMax = 13;
...
// IPP: memory allocation
rangeIx = new float[13];
rangeIy = new float[1];
@then you initialize your memory:
@
for( int i=xMin; i<=xMax; i++ ) // 0 to i <= 13 --> 14 entries!!! --> memory corruption!--
rangeIx[i-xMin] = (float)i;
for( int j=yMin; j<=yMax; j++) // 0 to j <= 1 --> 2 entries!!! --> memory corruption!
rangeIy[j-yMin] = (float)j;
@A fix would be:
@
BADtools::BADtools( int xMin, int xMax, int yMin, int yMax ){
hasParameters = true;
sFieldX = xMax - xMin + 1; // if you want to run from min to max, you need one more than max-min!!!
sFieldY = yMax - yMin + 1; // if you want to run from min to max, you need one more than max-min!!!
if(sFieldX > sFieldY) sMax = sFieldX;
else sMax = sFieldY;// IPP: memory allocation rangeIx = new float[sFieldX]; rangeIy = new float[sFieldY]; // Asymmetric ranges: for building inputs for( int i=xMin; i<=xMax; i++ ) rangeIx[i-xMin] = (float)i; for( int j=yMin; j<=yMax; j++) rangeIy[j-yMin] = (float)j; cout << "4Args badTools: initialized!" << endl;
}
@
-
Yeap, I saw that one too... what I did was to limit the for loops:
@for( int i=Min; i<Max; i++)@ instead of doing <=.
After wasting the whole day trying to find these and other errors I managed to create a simple project where I get two different results depending on the tool I use, qmake or cmake.
When using CMake to compile this project everything works as it should, when using qmake I get a symbol lookup error like this:path2/qtTools/build-qt/qtTest: symbol lookup error: /path2/qtTools/build-qt/qtTest: undefined symbol: _ZN3BAD8BADtoolsC1Eiiii
I hope you guys have some time to check this up, thanks in advance for your help.
Boris
"QtTest--: here...":https://docs.google.com/leaf?id=0B9kC5AeCp_q7NTQwNjIwODQtZjRjMi00ODc5LTllNDEtNjRmZmVhYjExOTdl&hl=en&authkey=CJbyracM
PS: running the Qt version with GDB gives me no chance to backtrace the error since it closes the window with the same error I wrote above plus it gives a Program exited with code 0177.
PS2: At the end of the day I couldn't run the binary in QtCreator, only in a terminal... very strange, in QtCreator keeps on saying that it can not find a library that I'm not asking to find. But in the terminal I don't have this problem. -
The project is missing the implementation for badtools.h and the project files to create it, can you add a stub implementation, please. Not everyone has Linux running ;-)
For the qmake project: It does not find the library. Make sure to have the following in your .pro:
@
LIBS += -L../myLib -lbadTools
@And for your execution problem: the linker is not finding your shared lib. Append the path to the myLib directory to the LD_LIBRARY_PATH variable (separated by colons ':') or create one if it does not exist. You can add it to the run environment in Creator.
If you change your lib to be linked statically (.a extension) you can save this step.
-
Hi Volker,
I have updated the project with the files that you asked... I didn't think they were need since I put the library but it is true what you said... didn't think about other systems. I don't know what a "stub implementation" is referred to but if you guide me to do one I'll do it as soon as possible, in any case all sources are here. The files are quite simple so it could be possible just to implement them in other platforms, right?
As for QtCreator not finding the library, I have confirmed several times that the library exists in the path, I make a CLEAN project, then I change the name to something like -lbadTls, for example, then I get a:
@
cannot find -lbadTls
collect2: ld returned 1 exit status
@
I put back -lbadTools and REBUILD the project, it builds it with no problems so that confirms that it is finding the library that I want in the path that I want; then I try to run and I get
@
/path2/qtTest/build-qt/qtTest: error while loading shared libraries: libipps.so.7.0: cannot open shared object file: No such file or directory
@
libipps.so.7.0 is a library that I was using in a different project and if you see the .pro file or any other .h or .cpp I'm not using any function from those IPP libraries, I'm not calling that library at all... it's like QtCreator is confusing projects or having some kind of attachment issues :)
I have also tried the LD_LIBRAY_PATH advice but it doesn't seem to affect QtCreator, at least not for this project. I have done the "sudo ldconfig" after including the path to my libraries in LD_LIBRARY_PATH.
Here is the updated "project":https://docs.google.com/leaf?id=0B9kC5AeCp_q7NTQwNjIwODQtZjRjMi00ODc5LTllNDEtNjRmZmVhYjExOTdl&sort=name&layout=list&num=50, with all sources. -
Thanks for coming back with the update. I will have a look into it tomorrow - it's midnight here in Berlin, time to sleep soon :)
Just some quick notes:
- the missing libipps can be caused by another library, that you linked in and that depends on that
- in one of the .pro files, I saw that you had libbadTls in a subdir libs64, are you sure it is there?
- calling ldconfig is not needed after changing LD_LIBRARY_PATH, just make sure it is exported on the shell and/or set in the run config environment of Qt Creator (project pane, run settings, the lower part)
-
Solved!!!
Thanks Gerolf and Volker, the solution was to add the path to my libraries within the LD_LIBRARY_PATH, I didn't know how to do that in QtCreator but I just add it inside "Clean Environment" like:
Variable: LD_LIBRARY_PATH
Value: $LD_LIBRARY_PATH:/path/to/my/libs
I would have thought that having:
LIBS += -L$$PATH2MYLIBS -lmylib
in the .pro file would be enough to find my libraries, do you know why I need to have this path in both places? Thanks again for your help guys.
Boris -
The .pro file is used to generate the Makefiles which instructs the build time linker where to find the libraries.
$LD_LIBRARY_PATH is used by the run-time linker to indicate additional search paths in which to look for libraries.
You can hard-code in library search paths into your apps/libs using rpath (-R option in gcc).
You can read more on this "here":http://www.eyrie.org/~eagle/notes/rpath.html.
-
For Linux users:
I kept on having problems when attempting to run the application built in QtCreator, I tried the -R option but it didn't work. In the end I found out somewhere on internet that I should create a myLibs.conf file inside /etc/ld.so.conf.d with the path to my libraries. That did the trick, fyi.Boris