Thread: invalid pointer conversion

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    42

    invalid pointer conversion

    Hello,
    Consider following code:

    Code:
    void foo(int **arr);
     
    int main()
    {
        int array[10][10];
        int **ptr;
        
        ptr = array; // error here
        
        foo(array);  // here aswell
        printf("%d", array); 
     
        getchar();    
        return  0; 
    }
    
    
    void foo(int **arr) 
    {
         printf("Hello\n");
    }
    What's wrong with this? I've tried same code in C, it works except that complier throws warning about incompatible pointers, while in C++ it's an error - any ideas?

  2. #2
    Registered User Noir's Avatar
    Join Date
    Mar 2007
    Posts
    218
    A 2D array isn't a pointer to a pointer, it's an array of pointers. These are the two types you're trying to mix, and they're not compatible:
    Code:
    int **
    int (*)[10]

  3. #3
    Registered User pronecracker's Avatar
    Join Date
    Oct 2006
    Location
    netherlands
    Posts
    158
    And how would you declare a pointer to an array of arrays of four bytes? If you don't know how many groups of four bytes there will be?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > void foo(int **arr);
    Would be
    void foo(int (*arr)[10]);
    or more simply
    void foo(int arr[ ][10]);
    or even just copy/paste for the lazy
    void foo(int array[10][10]);
    The definition of course follows the prototype.

    The pointer in main() follows the same logic, say
    int (*ptr)[10] = 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.

  5. #5
    Registered User Noir's Avatar
    Join Date
    Mar 2007
    Posts
    218
    It depends on how the groups were defined to begin with. If it's a 2D array that you just don't know the size of the first dimension you can do the same thing:
    Code:
    char (*p)[4];
    It's probably not an array though if you don't know the size of one of the dimensions. It's probably something dynamically allocated, and this has the best chance of working:
    Code:
    char **p;
    because this is the most common way to allocate memory for a 2D array:
    Code:
    char **p = new char*[n];
    
    for ( int i = 0; i < n; i++ ) {
      p = new char[4];
    }
    But if the memory is allocated like this the first way is the one you want:
    Code:
    int (*p)[4] = new int[n][4];

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    because this is the most common way to allocate memory for a 2D array:
    Not really - there better things to do with memory than wasting it on pointers and allocation overhead.

    The most common way is to allocate a 1D array and do index calculations.
    Last edited by CornedBee; 04-13-2007 at 10:23 AM. Reason: Rephrasing
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Registered User
    Join Date
    Nov 2006
    Posts
    42
    What if, say I got 2 local arrays:
    Code:
    int array1[10][10];
    int array2[100][100];
    ...and I want to create a function that could take any of them as an argument?
    Well, if I call malloc to allocate memory for those arrays, then it's no problem. But what if I want to keep it like that, and making foo() able to take either array1 or array2?

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    One way is to flatten the array and then pass the first element to your function.

    void foo ( int *array, size_t total_x, size_t total_y );

    ...

    foo( &array1[0][0], total_x, total_y );

    You have to do some arithmatic like this_x * total_y + index to access it correctly, but it shouldn't be too much of a problem.
    Last edited by whiteflags; 04-13-2007 at 12:25 PM.

  9. #9
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Quote Originally Posted by jimzy View Post
    What if, say I got 2 local arrays:
    Code:
    int array1[10][10];
    int array2[100][100];
    ...and I want to create a function that could take any of them as an argument?
    Well, if I call malloc to allocate memory for those arrays, then it's no problem. But what if I want to keep it like that, and making foo() able to take either array1 or array2?
    This comes up a lot in interfacing with apis. For example, you have to do it to use libpng since it deals with arbitrary sized 2d arrays. You have to do some preprocessing.

    Code:
    {
       int array1[10][10];
       int * array1_rows[10];
       
       for (i = 0; i < 10; ++i) {
          array1_rows[i] = &array1[i][0];
       }
       
       // Now, array1[x][y] == array1_rows[x][y], but array1_rows can be passed to int** functions as a 2d array.
    }
    Callou collei we'll code the way
    Of prime numbers and pings!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 04-04-2009, 03:45 AM
  2. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  3. invalid conversion from `char*' to `char'
    By Tommy7 in forum C++ Programming
    Replies: 3
    Last Post: 06-09-2005, 10:45 PM
  4. nonportable pointer conversion
    By _Cl0wn_ in forum C Programming
    Replies: 3
    Last Post: 01-23-2003, 05:03 AM
  5. Replies: 2
    Last Post: 02-07-2002, 09:39 AM