0

Let's consider the following C code :

char matrix[10][10];
char** array;

array = matrix;
printf("%c", array[2][3]);

I have a warning on line array = matrix : assignment from incompatible pointer type
I guess it's because the first array has been declared statically and the second one has been declared dynamically, but the real problem is on the printf line. The program simply crashes.
I can't seem to access a char** with [][] operators.
How can I fix that ?

NOTE: I simplified the context a little bit. In the original program, array is assigned through a function which return type is char** but actually returns a char[10][10].

deqyra
  • 734
  • 1
  • 7
  • 23
  • "I can't seem to access a char** with [][] operators.". Your theory is wrong. You don't have a `char**` to begin with. You have a `char[10][10]`, which you try to coerce into being a `char**`, which you can't, which is what the warning is telling you. – n. m. could be an AI Nov 03 '14 at 16:41
  • The second one is not "declared dynamically", is assigning what is supposed to be a `pointer to a pointer` to a `pointer to an array of pointers`. Also, if you want a dynamic allocation of a multidimensional array, you're gonna _have_ to specify all of its dimensions but the first one. – mccc Nov 03 '14 at 16:44

3 Answers3

1

A char array[10][10] doesn't decay to a char** but a char*. A multidimensional array is contiguous in memory, but a char** is a pointer to a pointer meaning that each 'row' would not be guaranteed to be next to each other in memory.

Ie array[10][10] looks like this in memory

&array (type char*)
|
| (points to)
|
\/
|---row/array one of length 10 chars---|---row/array two of length 10 chars---|...|---row/array ten of length 10 chars---|

which is not really any different from

&array (type char*)
|
| (points to)
|
\/
|---array of length 100 chars---|

So it is more or less like char[100] but just accessed differently.

On the other hand a char** p2p would work like

p2p (type char **) (points to array of pointers which is contiguous in memory) 
|
| (points to)
|
\/
|---pointer to first row of chars---|---pointer to second row of chars---|...
                 |                                    |
                 | (points to)                        |  (points to)
                 |                                    |
                 \/                                   \/
|****************|--row/array of chars--|*************|-- row/array of chars--|********

where *** is an arbitrary bit of memory of unknown size. In fact there is no guarantee the last set of arrays is in any particular order at all, let alone anything about them being next to each other (ie the last set of arrows could 'cross' each other.

user3353819
  • 911
  • 2
  • 8
  • 21
1

char** is different from char[10][10]. It is probably easiest to explain the problem when we show how a char** is stored in memory, compared to how a char[N][N] is stored.

For example, imagine a char[3][3] array initialized like this:

char matrix[3][3];
int count = 0;
for(int i = 0; i < 3; ++i)
{
    for(int j = 0; j < 3; ++j)
    {
        matrix[i][j] = count++;
    }
}

This would be laid out in memory something like this:

0 1 2 3 4 5 6 7 8 9

Notice, that the elements are laid out sequentially in memory with no pointers.

The variable matrix can also be interpreted as a char[3]* which points to the first element in the array.

Dereferencing a char[3]* returns a char[3] array, which can in turn be dereferenced with another [] operator. So element 0 of matrix can be thought of as the array [0, 1, 2]. We can use another [] operator to dereference a particular element of that array.

A char** on the other hand returns a char* when dereferenced. Accessing a particular element of a char** gives a char*. In our example above, accessing element 0 of our array matrix returns the value 0. This is then treated as a char* and using another [] operator to dereference it will try to access a char at memory location 0 + some offset. This will almost certainly cause a segfault.

Daniel
  • 6,595
  • 9
  • 38
  • 70
  • Oh, ok, I got it. [This](http://stackoverflow.com/questions/3911244/confusion-about-pointers-and-multidimensional-arrays) helped too. – deqyra Nov 03 '14 at 17:51
0

If you want a pointer to your character array then you can create a pointer and point it to the row which you need to access like shown below.

   int main()
    {
    char matrix[10][10];
    char* array;

    matrix[2][3] = 'c';
    array= matrix[2];
    printf("%c", array[3]);
    return 0;
    }
Gopi
  • 19,784
  • 4
  • 24
  • 36