Search code examples
carrayspointers

Pointer to 2D arrays in C


I know there is several questions about that which gives good (and working) solutions, but none IMHO which says clearly what is the best way to achieve this. So, suppose we have some 2D array :

int tab1[100][280];

We want to make a pointer that points to this 2D array. To achieve this, we can do :

int (*pointer)[280]; // pointer creation
pointer = tab1; //assignation
pointer[5][12] = 517; // use
int myint = pointer[5][12]; // use

or, alternatively :

int (*pointer)[100][280]; // pointer creation
pointer = &tab1; //assignation
(*pointer)[5][12] = 517; // use
int myint = (*pointer)[5][12]; // use 

OK, both seems to work well. Now I would like to know :

  • what is the best way, the 1st or the 2nd ?
  • are both equals for the compiler ? (speed, perf...)
  • is one of these solutions eating more memory than the other ?
  • what is the more frequently used by developers ?

Solution

  • //defines an array of 280 pointers (1120 or 2240 bytes)
    int  *pointer1 [280];
    
    //defines a pointer (4 or 8 bytes depending on 32/64 bits platform)
    int (*pointer2)[280];      //pointer to an array of 280 integers
    int (*pointer3)[100][280]; //pointer to an 2D array of 100*280 integers
    

    Using pointer2 or pointer3 produce the same binary except manipulations as ++pointer2 as pointed out by WhozCraig.

    I recommend using typedef (producing same binary code as above pointer3)

    typedef int myType[100][280];
    myType *pointer3;
    

    Note: Since C++11, you can also use keyword using instead of typedef

    using myType = int[100][280];
    myType *pointer3;
    

    in your example:

    myType *pointer;                // pointer creation
    pointer = &tab1;                // assignation
    (*pointer)[5][12] = 517;        // set (write)
    int myint = (*pointer)[5][12];  // get (read)
    

    Note: If the array tab1 is used within a function body => this array will be placed within the call stack memory. But the stack size is limited. Using arrays bigger than the free memory stack produces a stack overflow crash.

    The full snippet is online-compilable at gcc.godbolt.org

    int main()
    {
        //defines an array of 280 pointers (1120 or 2240 bytes)
        int  *pointer1 [280];
        static_assert( sizeof(pointer1) == 2240, "" );
    
        //defines a pointer (4 or 8 bytes depending on 32/64 bits platform)
        int (*pointer2)[280];      //pointer to an array of 280 integers
        int (*pointer3)[100][280]; //pointer to an 2D array of 100*280 integers  
        static_assert( sizeof(pointer2) == 8, "" );
        static_assert( sizeof(pointer3) == 8, "" );
    
        // Use 'typedef' (or 'using' if you use a modern C++ compiler)
        typedef int myType[100][280];
        //using myType = int[100][280];
        
        int tab1[100][280];
        
        myType *pointer;                // pointer creation
        pointer = &tab1;                // assignation
        (*pointer)[5][12] = 517;        // set (write)
        int myint = (*pointer)[5][12];  // get (read)
      
        return myint;
    }