0

I have seen many online resources about accessing the 2D array in C and all shows only one answer *( *(arr + i) + j)) But Unfortunately, it gave me this error

error: invalid type argument of unary ‘*’ (have ‘int’)
 27 |      printf("%d ",*(*(arr + i) + j));

My code:

void pointer_string_array_indexing(char *arr){
        
        for (int i = 0; i < 2; ++i)
        {
            
            for (int j = 0; j < 4; ++j)
        {
            //printf("%c : %d ",*(arr+4*i+j),(arr+4*i+j)); //this will give correct answer
            printf("%c ",*( *(arr + i) + j)); // compilation error
        }
        printf("\n");
        }
        
    }

int main(){
    char S[][4] = {"abc","efg"};
    pointer_string_array_indexing(S);
return 0;

}

I know this is a very famous & repeating question, but please provide code snippet of solution. I am using Ubuntu-20 (however it doesn't matter)

8
  • 1
    Please share some of those "many resources" (so we can show you where you misinterpret them). And share your error. Commented Dec 18, 2020 at 16:10
  • @JHBonarius here I am giving 2 links, geeksforgeeks.org/pointer-array-array-pointer overiq.com/c-programming-101/pointers-and-2-d-arrays Commented Dec 18, 2020 at 16:25
  • @user3121023 Yes it is working, Can you please elaborate your answer why it is working & Where I am doing wrong in my code? Commented Dec 18, 2020 at 16:26
  • A quick glance show the sources copied each other. But anyhow, none of the sources give an example how to pass a 2D array to a function, so you need better sources. Commented Dec 18, 2020 at 16:29
  • 2
    *( *(arr + i) + j) is a super convoluted way of writing arr[i][j]. Commented Dec 18, 2020 at 16:38

1 Answer 1

1

To understand why one way works and the other doesn't, you have to understand some of the strange things about how C allocates strings and arrays, and why sometimes strings are arrays and sometimes they are pointers.

Your array is declared as char S[][4]. All the characters in S are in a contiguous block in memory. When you access S[i][j], the compiled code determines the address of the character you are referencing by calculating the offset represented by i and j like char *indexed_character_address = S + i*4 + j. Now the compiled code uses indexed_character_address to load from or store into, depending on how S[i][j] is being used.

Another very different but confusingly similar way to declare an array of strings is like this:

char *T[] = { "tuv", "wxyz" };

What the compiler does behind the scenes to produce this array is very similar to this:

const char hidden_tuv[4] = { 't', 'u', 'v', '\0' };
const char hidden_wxyz[5] = { 'w', 'x', 'y', 'z', '\0' };
char *T[2] = { hidden_tuv, hidden_wxyz };

The "tuv" and "wxyz" strings are first placed in some arbitrary place, there is no guarantee which will come first or that they will be anywhere close to each other. Then another array is created and initialized with those two arbitrary pointers.

Code the compiler generates to access T[i][j] works in a manner very different from that for S. First it calculates the address of the ith string pointer in T, then it loads one of the string's starting addresses from memory, then it uses j to offset from the start of that address. Like this:

char **address_in_T = T + i;
char *string_start_address = *address_in_T;
// now string_start_address is either hidden_tuv or hidden_wxyz
char *indexed_character_address = string_start_address + j;

That verbose code is equivalent to this small expression:

char *indexed_character_address = T[i] + j;
                          //    or &(T[i][j])
                          //    or *(*(T + i) + j)

Your S variable is a 2-dimensional array of characters, initialized with string data, with type char[2][4]. My T variable is a 1-dimensional array of character pointers, of type (char *)[2].

The really really confusing part here is that even though these two variables are of very different types, C syntax can make accessing them look very similar

char c1 = S[i][j];   // actually reads *(S + i*4 + j)
char c2 = T[i][j];    // actually reads *( *(T + i) + j)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.