Results 1 to 17 of 17

Thread: Problems passing an array of pointers to objects to a function

  1. #1
    Join Date
    Aug 2006
    Posts
    163
    Thanks
    12
    Thanked 5 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Problems passing an array of pointers to objects to a function

    I have a rather odd problem. I am trying to pass an array of pointers to objects to a function, which initializes and fills the array. It then returns the number of pointers to objects in the array. The code looks something like this:

    Qt Code:
    1. class Material(){..}
    2.  
    3. class MaterialLoader(){
    4. ...
    5. LoadMaterial(const char *path, Material *materials[] ){...}
    6. }
    To copy to clipboard, switch view to plain text mode 

    The wierd thing is, when the LoadMaterial function is called from another class like this:

    Qt Code:
    1. Material **materials = NULL;
    2. MaterialLoader ml;
    3. int num_materials = ml.LoadMaterial(path, materials);
    4. printf("adress of materials is %x\n", materials);
    To copy to clipboard, switch view to plain text mode 

    the printf points to 0! The array is getting filled within the function, debugging the application as well as printf statements inside LoadMaterial confirm this. It is as though a copy is being made of materials, and that this is being passed to the function, but that's not possible, is it? And yet it must be, since that seems to be what is happening.

    Can someone shed some light on this? If you want to compile the code, it can be obtained from http://code.google.com/p/mll/

    Thanks in advance.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Problems passing an array of pointers to objects to a function

    This is a simple model of your error:
    Qt Code:
    1. void changeX( int x ) { x = 5; }
    2. ...
    3. int x = 0;
    4. changeX( x );
    5. printf( "%d\n", x );
    To copy to clipboard, switch view to plain text mode 
    Do you see now why it isn't going to work?

  3. #3
    Join Date
    Aug 2006
    Posts
    163
    Thanks
    12
    Thanked 5 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    It wouldn't work in the case you propose because you are not passing a pointer, so a copy is being made of x. Your analogy is wrong however, I feel. A better approximation of the problem would be:

    Qt Code:
    1. void changeX( int *x )
    2. {
    3. x = new int;
    4. *x = 5;
    5. }
    6. ...
    7. int *x;
    8. changeX( x );
    9. printf( "%d\n", *x );
    To copy to clipboard, switch view to plain text mode 
    which should work, since a pointer is being passed.

  4. #4
    Join Date
    Aug 2006
    Posts
    163
    Thanks
    12
    Thanked 5 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    Alternatively, if there is indeed a copy being made, how can I avoid this? I normally pass pointers like this:

    Qt Code:
    1. void changeX( int &x )
    To copy to clipboard, switch view to plain text mode 

    This avoids this problem. however, I can't find out how to pass an array of pointers to objects in this fashion.

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Problems passing an array of pointers to objects to a function

    Quote Originally Posted by Valheru View Post
    which should work, since a pointer is being passed.
    It's a classical "passing pointers in C" problem. You'd have to pass a pointer to the pointer if you wanted to modify it. Currently you are passing a copy of the pointer which points to zero and that copy is initialized to the newly allocated chunk of memory, leaving the original pointer intact (set to zero or whatever else was there) so Jacek's example correctly shows what happens. The type used is irrelevant here.

    A C++ way of doing what you want would be to pass a reference to the pointer. A C way of the same would be to pass a pointer to the pointer.

  6. #6
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    side note: print pointers with %p please, not with %x; this will safe you trouble on 64 bit platforms, among other things.


    You declare materials to be an array of pointers (to Material).
    Note the difference to "a pointer to an array of Materials".

    Fix: three possibilities
    1) (the best) use C++ containers like std::list, QList etc
    2) pass Material ***materials to your function and initialize with
    *materials = new Material *[num_materials]
    change all the usages to (*materials)[cur_material]->...
    3) decide that what you wanted was actually to pass a pointer to an array of Material objects:
    change the call to: Material ** materials
    then initialize with: * materials = new Materials[num_materials];
    change the usages to (*materials)[cur_material]. ...



    Basic idea:
    An array (in C unfortunately) is basically the same as a pointer (suggestion: why don't you use std::list, or QList or something like that? Makes codes more readable and less error prone.)
    So: your *Material[] is the same thing as Material**, it says: an array (or pointer to) Material-Pointers. It does not say a pointer to an array!

    You want the function to initialize your pointer, so you pass a pointer to the pointer...

    Then:
    you have to set that pointer (with *materials = ) somewhere in the function you call.


    Finally: This code does not make a lot of sense:
    Qt Code:
    1. cout << "Initial adress of materials inside LoadMaterials is " << &materials << "(should still be 0)" << endl;
    To copy to clipboard, switch view to plain text mode 
    materials is a Material**, passed on the stack.
    Therefore you are printing the address of a stack variable, here. This should not (and will not) be zero. Moreover, it is not interesting at all.
    What you really want to print here is
    Qt Code:
    1. materials
    To copy to clipboard, switch view to plain text mode 
    , not &materials.


    Your code illustrates nicely that using several layers of pointers, in combination with C-style arrays is a nice way to make your head spin and produce buggy code. Do use C++ containers to make your life easier.
    (The only reason not to use them is if you need to interface to C code.)

    HTH

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Problems passing an array of pointers to objects to a function

    Quote Originally Posted by Valheru View Post
    I can't find out how to pass an array of pointers to objects in this fashion.
    You can always ask c++decl:
    $ c++decl
    Type `help' or `?' for help
    c++decl> declare reference to array of pointer to int
    Warning: Unsupported in C++ -- 'Reference to array of unspecified dimension'
    (maybe you mean "reference to object")
    int *(&var)[]
    c++decl> declare reference to pointer to pointer to int
    int **&var
    (of course you will have to use the latter, as the warning says).

    Although some coding styles say that if the function modifies its argument you should use a pointer instead of a reference, so that you can clearly see that in the code. Compare this two:
    Qt Code:
    1. changeX( a, b, c, x );
    2. changeX( a, b, c, &x ); // <- here you see exactly which argument is going to be changed
    To copy to clipboard, switch view to plain text mode 

  8. #8
    Join Date
    Aug 2006
    Posts
    163
    Thanks
    12
    Thanked 5 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    Ok, first : thanks to you all for your help. It's a tremendous help understanding all this.

    Secondly, about my choice of container: I would like to keep it this way as opposed to using the infinitely easier vector solution. The reason for this is that I would like to pass the arrays later on to VBO's for example, and then they can be passed directly without any conversion.

    As I understand it, probably the correct way to pass the array of pointers to Material objects would be:

    Qt Code:
    1. LoadMaterials( const char &path, Material **&materials)
    To copy to clipboard, switch view to plain text mode 

    edit: Thanks, I have got it now. The original syntax is now valid passing Material **&materials in the function. I had expected to use "." accessors instead of "->" acessors though, but no.

    Now I have an older problem back, namely that calling delete[] on a variable triggers an error report about HEAP CORRUPTION saying:

    Qt Code:
    1. CRT detected that the application wrote to memory after end of heap buffer
    To copy to clipboard, switch view to plain text mode 

    Somewhere, I think I must be writing past the end of an array, but I can't for the life of me see where.
    Last edited by Valheru; 29th June 2008 at 19:58.

  9. #9
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    Please show us the piece of code ;-)
    (The error probably is either on of: 1) the variable was not initialized, 2) does not point to memory allocated on the heap, 3) it is on the heap, but not an array, 4) double free. Hard to guess, though.)

  10. #10
    Join Date
    Aug 2006
    Posts
    163
    Thanks
    12
    Thanked 5 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    Heh, I didn't expect you to guess though The complete code is available in the link in the first post: http://code.google.com/p/mll/source/checkout

    It's not a terrible lot though. The place where it is going wrong is where I delete[] name and material_path, although the corruption is probably happening before that.

  11. #11
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    you create a vector of num_materials elements, and then add with push_back. That way you end up with a vector of 2x num_materials elements, I think.
    Probably you want to call reserve, instead.

    side note:
    Qt Code:
    1. if( materials != NULL )
    2. delete materials;
    To copy to clipboard, switch view to plain text mode 
    These checks are not useful. Don't hurt either, though.

  12. #12
    Join Date
    Aug 2006
    Posts
    163
    Thanks
    12
    Thanked 5 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    Oh God, what a stupid mistake

    Qt Code:
    1. else if( buffer.substr( 0, 1 ) == "o" ){
    2. name = new char[buffer.length() - 2];
    3. sscanf(buffer.c_str(), "o %s", name);
    To copy to clipboard, switch view to plain text mode 

    I was allocating like that for certain variables. But I was not allowing space for the terminating \0 like that. It should have been buffer.length() - 1, obviously.

  13. #13
    Join Date
    Aug 2006
    Posts
    163
    Thanks
    12
    Thanked 5 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    Quote Originally Posted by caduel View Post
    you create a vector of num_materials elements, and then add with push_back. That way you end up with a vector of 2x num_materials elements, I think.
    Probably you want to call reserve, instead.

    side note:
    Qt Code:
    1. if( materials != NULL )
    2. delete materials;
    To copy to clipboard, switch view to plain text mode 
    These checks are not useful. Don't hurt either, though.
    I thought that calling delete on a variable that has been set to NULL causes a segfault? I pass a lot of variables into the function set to NULL by default, since not every variable has to be defined in an OBJ file.

  14. #14
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    You allocate materials as a pointer to std::vector, but free it as an array with delete[].
    Change that to delete and you should be ok.

    HTH

  15. #15
    Join Date
    Aug 2006
    Posts
    163
    Thanks
    12
    Thanked 5 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    Quote Originally Posted by caduel View Post
    You allocate materials as a pointer to std::vector, but free it as an array with delete[].
    Change that to delete and you should be ok.

    HTH
    You lost me. I don't allocate anything as a vector. Could you point to the file and line that that happens according to you?

  16. #16
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    i) delete NULL is absolutely fine (just as free(NULL))

    ii) When I browsed your svn repository online, I found such a line.
    But it is not there. Perhaps I somehow git into an older revision. Sorry.

    Any issues left?

  17. #17
    Join Date
    Aug 2006
    Posts
    163
    Thanks
    12
    Thanked 5 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems passing an array of pointers to objects to a function

    Well, the program is still crashing on some files. I don't know why though, it does it when I call delete <var>. It differs per file. Sometimes it happens when I am deleting the normal_idx array, etc. I hesitate to use vectors, since with many allocations of models it would, I feel, introduce unwelcome memory usage - especially since there is no need to dynamically grow the arrays.

    I'm trying to track it down now, although it may take a while. I'm learning a lot from it though, so I don't really mind too much, as long as it doesn't take too long

Similar Threads

  1. QPSQL problem
    By LoneWolf in forum Installation and Deployment
    Replies: 60
    Last Post: 4th November 2009, 15:22
  2. QPSQL driver in windows
    By brevleq in forum Installation and Deployment
    Replies: 31
    Last Post: 14th December 2007, 13:57
  3. how to add static library into qmake
    By Namrata in forum Qt Tools
    Replies: 1
    Last Post: 20th November 2007, 18:33
  4. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 07:13
  5. use qpsql
    By raphaelf in forum Installation and Deployment
    Replies: 34
    Last Post: 22nd August 2006, 13:52

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.