C++ and Visual Studio 2008 Passing 2 Dimensional Array


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 2 of 2

Thread: C++ and Visual Studio 2008 Passing 2 Dimensional Array

  1. #1
    Join Date
    Apr 2009
    Posts
    1

    Thumbs down C++ and Visual Studio 2008 Passing 2 Dimensional Array

    I am not new to programming but I am new to C++. I have followed the directions of other sites of how to pass a two-dimensional array to a function. I am getting a confusing error. Please note that I have been working on this issue for two evenings. I tried to solve the problem myself before posting. I am also aware of the syntax of passing an array with the width defined. I am wanting to write a general use function and I don't want to be locked into any specific size.

    Thank you in advance.

    Here is my code:


    #include <iostream>

    using namespace std;

    void initialize2DCharArray(char** array, int height, int width, char initChar);

    void initialize2DCharArray(char** array, int height, int width, char initChar)
    {
    for(int colCount=0;colCount < height; colCount++)
    {
    for(int rowCount=0;rowCount < width; rowCount++)
    {
    array[rowCount][colCount] = initChar;
    }
    }
    }

    void main()
    {
    char c[3][3];

    initialize2DCharArray(c, 3, 3, 'A');
    }


    Here is the error:

    error C2664: 'initialize2DCharArray' : cannot convert parameter 1 from 'char [3][3]' to 'char **'
    Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

  2. #2
    Join Date
    Dec 2007
    Posts
    401
    @JavaEnthusiast : if you are already familiar with part 1, you may want to go directly to part 2.

    part 1
    ------

    it helps to first realize that arrays are *never* actually passed to functions. for example,

    Code:
    void foo( int array[] )
    {
      // ...
    }
    
    int main()
    {
      int a[20] ;
    }
    the type of the argument to foo is not "array of int", it is "pointer to int". in fact, it would be exactly the same if it were written as

    Code:
    void foo( int* array )
    {
      // ...
    }
    the name of an array is almost always converted to a pointer to the first element of that array. for example:

    Code:
    int b[20] ;
    b[3] = 100 ;
    the second line is equivalent to *( b + 3 ) = 100 ; where b is a pointer to the first element, and pointer arithmetic is used to reach the 3rd element. that line could just as well have been written this way:
    Code:
    3[b] = 100 ; // perfectly valid.
    this is equivalent to *( 3 + b ) = 100 ; which is equivalent to *( b + 3 ) = 100 ;

    once you grasp that array names almost always decay to a pointer to the first element, take another look at the function call from main() above: foo(a) ;. you should understand what this is really doing - it's *not* passing an int array named a to a function that expects an int array. it's passing an int pointer to a function that expects an int pointer. foo(a) ; is equivalent to foo( &( a[0] ) ) ;

    now, consider the case of a function (apparently) taking a two-dimensional array:

    Code:
    enum { SIZE = 10 } ;
    void bar( int array2d[][SIZE] )
    {
      // ...
    }
    we know better - this function does not take an array at all, but a pointer. we should think of multidimensional arrays in a different way in C:
    a 2d array is really a 1d array, each of whose elements is itself a 1d array. it could be equivalently written this way:

    Code:
    enum { SIZE = 10 } ;
    void bar( int (*array2d) [SIZE] )
    {
      // ...
    }
    it should begin to become clear now. the type of array2d is "pointer to array of SIZE ints". why does SIZE have to be specified? because it is required for evaluating array subscript operator which requires pointer arithmetic.
    array2d actually points to the first of several arrays of ints, and we want to access the third of those arrays: array2d[3] ; this is equivalent to *( array2d + 3 ). note that we are adding 3 to a pointer, and recall that because of pointer arithmetic the address required is 3 * sizeof( *array2d ) bytes past array2d.
    in order for the compiler to generate code for this, it needs to know ahead of time what sizeof( *array2d ) is. sizeof( *array2d ) is equivalent to sizeof( int[SIZE] ), therefore the compiler needs to know SIZE at compile time.

    it follows that any time you declare a function with an argument which is a multi-dimensional array, you need to specify the size of every dimension except the first; the sizes of those dimensions must be constants known at compile time.

    part 2
    ------

    if it's not possible to know the sizes of the dimensions until run time, there are several options. the simplest is to use a std::vector<> (which is much like a java array):
    Code:
    #include <vector>
    
    void foobar( std::vector< std::vector<int> >& two_d_vec )
    {
        // set all elements to 8
            for( std::size_t i = 0 ; i < two_d_vec.size() ; ++i )
                    for( std::size_t j = 0 ; j < two_d_vec[i].size() ; ++j )
                            two_d_vec[i][j] = 8 ;
    }
    
    int main()
    {
        typedef std::vector<int> array1d_type ;
        typedef std::vector<array1d_type> array2d_type ;
    
        // create a 5 X 4 array of int initialized to zero
        array2d_type a( 5U, array1d_type( 4U ) ) ;
    
            foobar(a) ;
    }
    a second option is to use an array of pointers:
    Code:
    void foobar2( int** array, ind rows, int cols )
    {
        // set all elements to 8
            for( int i = 0 ; i < rows ; ++i )
                    for( int j = 0 ; j < cols ; ++j )
                            array[i][j] = 8 ;
    }
    
    int main()
    {
       int ROWS = 5, COLS = 4 ;
       int** array = new int* [ ROWS ] ;
         
         for( int i = 0 ; i < ROWS ; ++i )
             array[i] = new int[COLS] ;
    
       foobar2( array ) ;                
    
         for( int i = 0 ; i < ROWS ; ++i )
             delete[] array[i] ;
       delete[] array ;             
    }
    a third option is to just use a one dimensional array to simulate a 2d array, and do the pointer arithmetic on our own:
    Code:
    void foobar3( int* array, int rows, int cols )
    {
        // set all elements to 8
            for( int i = 0 ; i < rows ; ++i )
                    for( int j = 0 ; j < cols ; ++j )
                            array [ i*cols + j ] = 8 ;
    }
    
    int main()
    {
       int ROWS = 5, COLS = 4 ;
       int* array = new int[ ROWS * COLS ] ;
    
       foobar3( array ) ;
    
         delete[] array ;              
    }
    an option which combines the above two ideas:
    Code:
    void foobar2( int** array, ind rows, int cols )
    {
        // set all elements to 8
            for( int i = 0 ; i < rows ; ++i )
                    for( int j = 0 ; j < cols ; ++j )
                            array[i][j] = 8 ;
    }
    
    int main()
    {
       int ROWS = 5, COLS = 4 ;
       int** array = new int* [ROWS] ;
         
       array[0] = new int[ ROWS * COLS ] ;
         
       for ( int i = 1 ; i < ROWS ; ++i ) 
           array[i] = array[i-1] + COLS ;
    
       foobar2( array ) ;
    
         delete[] array[0] ;
         delete[] array ;
    }
    Last edited by vijayan; 04-10-2009 at 02:33 AM.

Similar Threads

  1. Newbe to Visual Studio 2008
    By jnesbett in forum .NET
    Replies: 1
    Last Post: 03-30-2009, 03:36 PM
  2. YAG's public status report - March 7, 2002
    By Seth Grossman [MSFT] in forum vb.announcements
    Replies: 1
    Last Post: 03-13-2002, 07:32 PM
  3. YAG's status report - Feb 14, 2002
    By Seth Grossman [MSFT] in forum .NET
    Replies: 1
    Last Post: 02-15-2002, 12:35 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center