Pointer to 2D array

This is a discussion on Pointer to 2D array within the C Programming forums, part of the General Programming Boards category; Somthing isn't right here and I can't seem to figure it out. I want to define a variable type called ...

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    3

    Pointer to 2D array

    Somthing isn't right here and I can't seem to figure it out. I want to define a variable type called MATRIX4D as so:

    Code:
    typedef float MATRIX4D[4][4];
    In several functions I want to reference this type as a pointer such as:

    Code:
    MATRIX4D oMatrix;
    MATRIX4D *poMatrix = &oMatrix[0][0]
    func(poMatrix)];
    poMatrix seems to be 3D array now, and I get the following compile error:

    Code:
    error C2440: 'initializing' : cannot convert from 'float *' to 'float (*)[4][4]'
    Any help would be appreciated

    Thanks!

  2. #2
    cas
    cas is offline
    Registered User
    Join Date
    Sep 2007
    Posts
    982
    You're making it slightly too difficult. When you're typedefing like that, pretend like you don't know you have an array:
    Code:
    typedef float MATRIX4D[4][4];
    MATRIX4D oMatrix;
    MATRIX4D *poMatrix = &oMatrix;
    The syntax is like any simple pointer assignment.

    The reason you were getting the error is that poMatrix is literally a pointer to an array of array, whereas &oMatrix[0][0] is a pointer to a float (because oMatrix[0][0] is a float). They point to the same place (in so far as you can say two different types of pointer can point to the same place), but they are different types and thus are not compatible.

    Generally speaking, you don't need an explicit pointer to an array like that. Arrays decay into pointers anyway, so if you're trying to simulate a pass by reference, arrays magically do that already.
    Last edited by cas; 05-18-2009 at 08:20 PM. Reason: Oops.. superfluous asterisk removed.

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    3
    Thanks for clearing that up...

    Moving forwards, I defined the following function:

    Code:
    void ClearMatrix(MATRIX4D *poMatrix)
    {
          for(int row=0; row<4; row++)
          {
                for(int col=0;col<4;col++)
               {
                poMatrix[row][col] = (float)0;
                }
          }
    }
    This code is given me the following error message:
    Code:
    error C2440: '=' : cannot convert from 'const int' to 'float [4]'

    If I reference poMatrix as a pointer the error goes away

    Code:
    *poMatrix[row][col] = (float)0;

    I am using a C++ compiler, but in my experience with C compilers I never had to do this before.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    poMatrix is a pointer to a MATRIX4D, right? So poMatrix[row][col] is an array, still, assuming it exists (hint: probably not, given that row is going to move forward by entire MATRIX4D structures, and then col is going to move forward by rows). I'm guessing the asterisk in your function definition is not correct.

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    3
    Yeah, the asterisk did not work as expected and it only eliminated the error message.

    I'm not sure if I understand your hint. I have only defined this function, and I have not used it yet, so the address is not valid. The usage of the for-loops with the 2D array should not give me an error. I did get it working without using pointers as input arguments, but I prefer using pointers.

  6. #6
    cas
    cas is offline
    Registered User
    Join Date
    Sep 2007
    Posts
    982
    Since it's a pointer, you have to dereference. You're on the right track, but due to C's precedence, you need:
    Code:
    (*poMatrix)[row][col] = 0;
    Dereference poMatrix, which is a pointer to an array; then you have the array and can treat it as such. Casting 0 to float is unnecessary unless your compiler is stupid and warns about that.

    As I stated earlier, arrays passed into functions act like pass by reference, so unless you're trying to hide the fact that MATRIX4D is an array, there's really no reason to use a pointer to it.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Save yourself the headaches that is passing actual arrays around, and just use pointers.
    Code:
    void makematrix( float ***m, size_t rows, size_t columns )
    {
        if( m )
        {
            allocate rows
            for each row
                allocate columns
        }
    }
    
    ...
    
    float **matrix;
    
    ...
    
    makematrix( &matrix, 10, 20 );
    I find passing actual arrays far more of a headache than it's worth.


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by quzah View Post
    Save yourself the headaches that is passing actual arrays around, and just use pointers.
    Code:
    void makematrix( float ***m, size_t rows, size_t columns )
    {
        if( m )
        {
            allocate rows
            for each row
                allocate columns
        }
    }
    
    ...
    
    float **matrix;
    
    ...
    
    makematrix( &matrix, 10, 20 );
    I find passing actual arrays far more of a headache than it's worth.


    Quzah.
    Yes, but that causes a whole load of extra overhead:
    In terms of data storage since you now need to store 5 pointers to store 16 floats. So you spend 24 bytes [assuming pointers are 32-bit, on a 64-bit machine, it would be 48 bytes] storing 64 bytes of data. That assumes NO overhead on the allocations - which there likely is - each pointer block is usually rounded to some larger address.

    On the memory access front, each memory read of the matrix content would incur at least one extra memory read, probably two, where the fixed size array is a single direct read of the data - only a simple multiplication by 4 (or 16) and addition to get the address of each element.

    And due to the nature of pointers and compilers inability to understand aliasing, it is not unlikely that the compiler produces less good code from it simply because it doesn't know if the code does something like setting all rows to point to the same data.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Not really. But if you're worried about it, just use a single malloc call, and use one less layer of indirection.
    Code:
    void makematrix( float **m, size_t rows, size_t cols )
    {
        *m = malloc( sizeof **m * rows * cols );
    }
    Array work is all done by multiplication anyway.


    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by quzah View Post
    Not really. But if you're worried about it, just use a single malloc call, and use one less layer of indirection.
    Code:
    void makematrix( float **m, size_t rows, size_t cols )
    {
        *m = malloc( sizeof **m * rows * cols );
    }
    Array work is all done by multiplication anyway.


    Quzah.
    You still get one extra memory access, and now you can't use [row][col] syntax.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    How do you figure you're getting an extra memory access?
    Code:
    ptr[ (row * COL) + col ] = x;
    1 pointer accessed. Two if you count the fact that he was wanting to use a pointer to an array, but even with a pointer to an "actual array", you're still ending up with two.


    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 2D array pointer
    By taurus in forum C Programming
    Replies: 15
    Last Post: 10-30-2008, 12:30 PM
  2. Dynamic pointer array in C
    By MacFromOK in forum Windows Programming
    Replies: 14
    Last Post: 04-09-2005, 06:14 AM
  3. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM
  4. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM
  5. Hi, could someone help me with arrays?
    By goodn in forum C Programming
    Replies: 20
    Last Post: 10-18-2001, 09:48 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21