1

I am new to programming and C in general and the last few weeks I try to get the concept of pointers, arrays and how they are connected. At the moment I experiment with command line arguments in C and I read here on this platform that argv can be syntactically defined differently, however the semantic stays the same.

int main(int argc, char *argv[])

is equal to

int main(int argc, char **argv)

Okay, but why is my code behaving differently when I try to initialize an array in these ways:

char *s[] = {"hallo", "12345"};
printf("%c und %c", s[0][4], s[1][2]);

I get as output as expected: o and 3.

But when I initialize the array like

char **s = {"hallo", "12345"};
printf("%c und %c", s[0][4], s[1][2]);

I get a segmentation fault or other errors which I cannot understand like (near initialization for ‘s’)

I guess you cannot initialize an pointer to a pointer array with 2 asterisks. Maybe someone can provide me with more information about these relation and how these 2 definitions differ from each other.

phl92
  • 19
  • 4
  • 2
    The "equivalence" is true *only* for function parameters, like for `argv` in `main()`. It is *not* true for other arrays you might declare. The "equivalence" is due to the fact that an array is never passed as an array; it is always passed as a pointer; so the function can only ever receive a pointer. It is, arguably, safer to always explicitly declare function parameters (like `argv` in `main()`) as the pointers that they really are. – Steve Summit Jan 03 '23 at 22:36
  • 1
    There is a difference between declaring a variable as `char**arg/char*arg[]` and declaring a function with `char**arg`, in C, arrays decay to pointers, but on a local level, there is a difference between an array and a pointer, K&R's book has an insightful introduction to this difference. In function declarations `char**arg` is the same as `char*arg[]`, however in local scopes, one of these *knows* the size allocated (that's why you get a segfault, that memory was *not* allocated to the program) – greybrunix Jan 03 '23 at 22:39
  • 2
    You should know that before `main()` has been called, an array has been allocated and its elements set to point to each of the command line parameters (and a trailing NULL pointer, too, but that's for later.) Then the address of that array is the second parameter to the function `main()`. Where is the array in `char **myarr = ...`?? – Fe2O3 Jan 03 '23 at 22:48
  • 1
    Does [What is array to pointer decay?](/questions/1461432) answer your question? How about [Is an array name a pointer?](/questions/1641957)? Or [C pointer to array/array of pointers disambiguation](/questions/859634)? Or [What is the difference between char array and char pointer in C?](/questions/10186765)? – Karl Knechtel Jan 03 '23 at 23:00

1 Answers1

0

They are completely different:

  1. char *s[]

is an array of pointers. Arrays cannot be assigned or used as values

This code will not compile:

char *a[] = {"hallo", "12345"};
char *a1[2];
char **s = (char *[]){"hallo", "12345"};
char **s1;

void foo(void)
{
    a++;
}

void bar(void)
{
    a1 = a;
}
  1. char **s

is a pointer to a pointer and can be assigned or used as an lvalue.

This code will compile:

char *a[] = {"hallo", "12345"};
char *a1[2];
char **s = (char *[]){"hallo", "12345"};
char **s1;

void foo(void)
{
    s++;
}

void bar(void)
{
    s1 = s;
}

https://godbolt.org/z/vqxv913WY

0___________
  • 60,014
  • 4
  • 34
  • 74