Asked  6 Months ago    Answers:  5   Viewed   25 times
int main()
{
    matrix[2][4] = {{11,22,33,99},{44,55,66,110}};
    int **ptr = (int**)matrix;
    printf("%d%d",**matrix,*ptr);
}

But when a 2-d array is passed as a parameter it is typecasted into (*matrix)[2] .. what type does the compiler store this array as... is it storing as a 2-d array or a double pointer or an pointer to an array .. If it is storing as an array how does it interprets differently at different situations like above. Please help me understand.

 Answers

17

Is 2d array a double pointer?

No. This line of your program is incorrect:

int **ptr = (int**)matrix;

This answer deals with the same topic

If you want concrete image how multidimensional arrays are implemented:

The rules for multidimensional arrays are not different from those for ordinary arrays, just substitute the "inner" array type as element type. The array items are stored in memory directly after each other:

matrix: 11 22 33 99 44 55 66 110
        -----------               the first element of matrix
                    ------------  the second element of matrix

Therefore, to address element matrix[x][y], you take the base address of matrix + x*4 + y (4 is the inner array size).

When arrays are passed to functions, they decay to pointers to their first element. As you noticed, this would be int (*)[4]. The 4 in the type would then tell the compiler the size of the inner type, which is why it works. When doing pointer arithmetic on a similar pointer, the compiler adds multiples of the element size, so for matrix_ptr[x][y], you get matrix_ptr + x*4 + y, which is exactly the same as above.

The cast ptr=(int**)matrix is therefore incorrect. For once, *ptr would mean a pointer value stored at address of matrix, but there isn't any. Secondly, There isn't a pointer to matrix[1] anywhere in the memory of the program.

Note: the calculations in this post assume sizeof(int)==1, to avoid unnecessary complexity.

Tuesday, June 1, 2021
 
tiny
answered 6 Months ago
32

You are incorrect; jagged (nested) arrays are faster. (the CLR is optimized for them)

Java does not support true multi-dimensional arrays; that's a jagged array.
The Java syntax automatically creates all of the inner arrays; in C#, that would need a separate loop.

Wednesday, July 21, 2021
 
NewPHP
answered 5 Months ago
96

When you declare the array keys you are saying to the compiler that you want to work with an array of 2 pointers to pointers to chars and ask it to initialize those pointers to pointer to char to NULL. All good.

Then you call add1(). All good.

Then you call add2() and try to put into the first element of b[0] the return value from malloc(). But the value of b[0] is NULL. The NULL was put there in the main() function. b[0] has no elements!

When you have arrays of arrays (of arrays ...) in the form of pointers you need to malloc() (and free()) every level individually.


Edit

#include <stdlib.h>

int main()
{
    char **keys[2] = {0};
    keys[0] = malloc(20 * sizeof *keys[0]); /* 20 strings */
    keys[1] = malloc(20 * sizeof *keys[1]); /* 20 strings */

    for (int k=0; k<20; k++) {
        keys[0][k] = malloc(120); /* string with 119 chars + '' */
        keys[1][k] = malloc(120); /* string with 119 chars + '' */
    }

    /* use k[0][0] through k[0][19] */
    /* use k[1][0] through k[1][19] */

    for (int k=0; k<20; k++) {
        free(keys[0][k]);
        free(keys[1][k]);
    }
    free(keys[0]);
    free(keys[1]);

    return 0;
}

I put it all in the main() function, but it's the same idea if the malloc()s and free()s are in their own function.

Saturday, August 21, 2021
 
binoculars
answered 4 Months ago
83

The strsep function requires the address of a modifiable pointer as its first argument (or NULL, in which case it does nothing); you are passing it the (fixed) address of an array. You can fix this by declaring a separate char* variable and assigning to that the (address of the) org array:

int main()
{
    char* token, org[] = "Cats,Dogs,Mice,,,Dwarves,Elves:High,Elves:Wood";
    char* porg = org; // "porg" is a MODIFIABLE pointer initialized with the start address of the "org" array
    while ((token = strsep(&porg, ",")))
        printf("Token: %sn", token);

    return 0;
}

From the Linux manual page (bolding mine):

If *stringp is NULL, the strsep() function returns NULL and does nothing else. Otherwise, this function finds the first token in the string *stringp, that is delimited by one of the bytes in the string delim. This token is terminated by overwriting the delimiter with a null byte (''), and *stringp is updated to point past the token. In case no delimiter was found, the token is taken to be the entire string *stringp, and *stringp is made NULL.

On the meaning and use of the restrict keyword, maybe this will help: Realistic usage of the C99 'restrict' keyword?.

Thursday, August 26, 2021
 
saad
answered 3 Months ago
42

An array of arrays is not the same as a pointer to a pointer.

Reason being that the memory layout is completely different.

For an array of arrays:

+-----------+-----------+-----------+-----------+
| arr[0][0] | arr[0][1] | arr[1][0] | arr[1][1] |
+-----------+-----------+-----------+-----------+

For a pointer to pointer:

+--------+--------+-----+
| arr[0] | arr[1] | ... |
+--------+--------+-----+
  |        |
  |        V
  |      +-----------+-----------+-----+
  |      | arr[1][0] | arr[1][1] | ... |
  |      +-----------+-----------+-----+
  V
+-----------+-----------+-----+
| arr[0][0] | arr[0][1] | ... |
+-----------+-----------+-----+

As arrays decays to pointer, you can have a pointer to arrays though:

int (*ptr)[2] = arr;
Wednesday, October 27, 2021
 
David Arno
answered 1 Month ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share