Thread: Conflict with double pointer

  1. #1
    Registered User
    Join Date
    Dec 2003
    Posts
    18

    Conflict with double pointer

    I was working on my tile engine in SDL and came across a problem to when using my double array(int TileMap[10][10]) as a parameter to this function call: void CTile:rawTiles( int** );
    I've tried the same thing in a smaller problem to see whats up.

    Code:
    #include <iostream>
    
       using std::cout;
       using std::cin;
       using std::endl;
    
       
       
    void SetArray( int** );
    
    
    int main( void )
    {
    
         int array[2][3]= { {14, 6, 4}, {6, 14, 7} };
         
         
         SetArray( array );
         
         
         cout << array[0][0] << endl;
    
    
         cin.get();
         return EXIT_SUCCESS;
    }
    
    
    void SetArray( int** array )
    {
    
         array[0][0]+= 7;
    }
    How can I make variable 'array' suitable for function void SetArray( int ** )?
    Language: HTML, JavaScript, C/C++. Python

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    A 2D array is not a **

    void SetArray( int[][3] );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2003
    Posts
    18
    Ok, but I want to use a similiar function in my Tile Engine. What if the programmer using doesn't want the size of the tile be 3? I would have to declare the function parameters a little differently.
    Language: HTML, JavaScript, C/C++. Python

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >What if the programmer using doesn't want the size of the tile be 3?
    Then you can use a double pointer and require them to allocate memory for whatever size matrix they want.
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Dec 2003
    Posts
    18
    Then you can use a double pointer and require them to allocate memory for whatever size matrix they want.
    Code:
    #include <iostream>
    
       using std::cout;
       using std::cin;
       using std::endl;
    
       
       
    void SetArray( int** );
    
    
    int main( void )
    {
    
         int **array= new int*[20];
    //     int array[2][3]= { {14, 6, 4}, {6, 14, 7} };
         array[0][0]= 7;
         
         
         SetArray( array );
         
         
         cout << array[0][0] << endl;
    
    
         delete [] array;
    
         cin.get();
         return EXIT_SUCCESS;
    }
    
    
    void SetArray( int** array )
    {
    
         array[0][0]+= 7;
    }
    Still doesn't work.
    Language: HTML, JavaScript, C/C++. Python

  6. #6
    Programming Sex-God Polymorphic OOP's Avatar
    Join Date
    Nov 2002
    Posts
    1,078
    Originally posted by Leiarchy9
    Ok, but I want to use a similiar function in my Tile Engine. What if the programmer using doesn't want the size of the tile be 3? I would have to declare the function parameters a little differently.
    Then I'd recommend using a matrix type. You can use boost's multi_array (boost.org), or make your own. To make your own, encapsulate a pointer and dynamically allocate an array of size width*height and then overload operator [] to return the pointer plus the row you are trying to access times the number of colums. This way you have a unified type for an nxm matrix so you can just make your function take a reference to the type and it will account for matrices of any size. I don't recommend using the pointer to pointer solution.

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Still doesn't work.
    That's because you aren't doing it right. To create a dynamically allocated matrix you need to do this:
    Code:
    T **matrix = new T*[m];
    for ( int i = 0; i < m; i++ )
      matrix[i] = new T[n];
    Then to release the memory, you do the opposite:
    Code:
    for ( int i = 0; i < m; i++ )
      delete [] matrix[i];
    delete [] matrix;
    Remember that you are working with a dynamic array of pointers that are each a dynamic array of type T.

    >I don't recommend using the pointer to pointer solution.
    There are advantages and disadvantages, but the pointer to pointer solution is generally easier to understand. Of course, it's better to avoid such low level manipulations in general unless the performance is required.
    My best code is written with the delete key.

  8. #8
    Registered User
    Join Date
    Dec 2003
    Posts
    18
    Works now.

    Code:
    #include <iostream>
    
       using std::cout;
       using std::cin;
       using std::endl;
    
       
       
    void SetArray( int** );
    
    
    int main( void )
    {
    
    
         const int m= 20, n= 20;
         int **array= new int*[m];
    
    
         for( int i= 0; i < m; i++ )
         {
         
            array[i]= new int[n];
         }
         
         
         array[0][0]= 7;
         SetArray( array );
         
         
         cout << array[0][0] << endl;
    
    
         for( int i= 0; i < m; i++ )
         {
         
            delete [] array[i];
         }
         delete [] array;
         
    
         cin.get();
         return EXIT_SUCCESS;
    }
    
    
    void SetArray( int** array )
    {
    
         array[0][0]+= 7;
    }
    I have no more problem. How can I initialize each element of 'array' in a easy/shortcut-like fashion? Like so:

    Code:
    // In your code, it is not possible to initialize 'array' like so:
    
    int array[20][20]= { {1, 1, 1, 1,}....well you get the idea
    
    // I don't want to initialize each element individual like this
    
    array[0][0]= 7;
    array[0][1]= 2;
    array[0][2]= 8;
    .......well, you get the point.
    
    //I assume you have a solution/shortcut for this?
    Language: HTML, JavaScript, C/C++. Python

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > How can I initialize each element of 'array' in a easy/shortcut-like fashion?
    Well if you dynamically allocated it, pretty much one at a time is all you can do.

    Unless of course, you also have a static array initialised with all your data and you want to copy it across to your dynamic array.

    But then, why exactly are you allocating the array? Is it just to fit in with some provided API?
    Because with a bit of effort, you can turn a 2D array into an array of pointers, without all this memory allocation....
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >//I assume you have a solution/shortcut for this?
    No, you have to do it manually with either a series of assignment statements, or a loop. Usually you will see something like this:
    Code:
    for ( int i = 0; i < m; i++ )
      for ( int j = 0; j < n; j++ )
        matrix[i][j] = default_value;
    But for dynamic initialization, you are on your own.
    My best code is written with the delete key.

  11. #11
    Registered User
    Join Date
    Sep 2003
    Posts
    135
    The following thread addressed much the same issues, you may find it useful:

    http://cboard.cprogramming.com/showt...threadid=46425

  12. #12
    Registered User
    Join Date
    Dec 2003
    Posts
    18
    Why isn't this working?

    Code:
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    
       using std::cout;
       using std::cin;
       using std::endl;
       
       int Map[2][4]= { {1, 1, 1, 1},
                        {1, 1, 1, 1} };
    
       template <typename N>
       void AllocateMemory( N**, int, int );
    
       template <typename N>
       void DeallocateMemory( N**, int );
    
    
    
    int main( void )
    {
    
         int **array;
         
         
         AllocateMemory<int>( array, 2, 4 );
         
    
         for( int j= 0; j < 2; j++ )
         {
         
            for( int k= 0; k < 4; k++ )
            {
            
               array[j][k]= Map[j][k];
            }
        }
    
    
         DeallocateMemory<int>( array, 2 );
    
         cin.get();
         return EXIT_SUCCESS;
    }
    
    
    template <typename N>
    void AllocateMemory( N** var, int groups, int elements )
    {
    
         var= new N*[ groups ];
         
         
         for( int i= 0; i < groups; i++ )
         {
         
            var[i]= new N[ elements ];
         }
         
    }
    
    
    template <typename N>
    void DeallocateMemory( N** var, int groups )
    {
    
         for( int i= 0; i < groups; i++ )
         {
    
            delete [] var[i];
         }
    
         delete [] var;
    }
    Last edited by Leiarchy9; 01-03-2004 at 04:19 PM.
    Language: HTML, JavaScript, C/C++. Python

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > void AllocateMemory( N**, int, int );
    The N** needs to be a reference if you want the value to be changed in the caller.
    As it stands, its just a local variable whose value is lost when the function returns.

    I see that you in fact do have a static array containing initialised data, and you're copying it to dynamically allocated memory.

    Code:
       int Map[2][4]= { {1, 1, 1, 1},
                        {1, 1, 1, 1} };
       int *array[2] = { Map[0], Map[1] };  // or use a loop
    
       // more stuff
       SetArray( array );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  14. #14
    Registered User
    Join Date
    Dec 2003
    Posts
    18
    The N** needs to be a reference if you want the value to be changed in the caller.
    Does the parameter/local variable('N** var') have to be referenced? How do I reference a double pointer?
    Language: HTML, JavaScript, C/C++. Python

  15. #15
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Code:
    template <typename N>
    void AllocateMemory( N**& var, int groups, int elements )
    {
    
         var= new N*[ groups ];
    
    
         for( int i= 0; i < groups; i++ )
         {
    
            var[i]= new N[ elements ];
         }
    
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. pointer with double asterisk
    By skringla in forum C Programming
    Replies: 10
    Last Post: 11-27-2008, 07:33 AM
  2. Copying 2-d arrays
    By Holtzy in forum C++ Programming
    Replies: 11
    Last Post: 03-14-2008, 03:44 PM
  3. C++ to C Conversion
    By dicon in forum C Programming
    Replies: 7
    Last Post: 06-11-2007, 08:38 PM
  4. Help with multi function progam
    By WackoWolf in forum C Programming
    Replies: 22
    Last Post: 10-13-2005, 02:56 AM
  5. Hi, could someone help me with arrays?
    By goodn in forum C Programming
    Replies: 20
    Last Post: 10-18-2001, 09:48 AM