why does the first one prints the string value whereas second give segfault?
What's happening in Case I:
The type of staticArray is char [100] i.e. array of 100 char.
The type of &staticArray is char (*)[100].
The %s format specifier in scanf() expect the argument as a pointer to initial element of char array i.e. of type char *.
You are passing char (*)[100] type to scanf(), hence compiler is giving warning on this statement.
The &staticArray give you pointer to the array of type char (*)[100] which is numerically same as the base address of array.
Consider this example:
#include <stdio.h>
int main(void)
{
char staticArray[100];
printf ("staticArray: %p\n", (void*)staticArray);
printf ("&staticArray : %p\n", (void*)&staticArray);
return 0;
}
Output:
## ./a.out
staticArray: 0x7ffee4044a70
&staticArray : 0x7ffee4044a70
staticArray and &staticArray both yield a pointer to the same address1) but their type is different.
That's why when you pass &staticArray to scanf(), getting warning during compilation due to type mismatch but when scanf() called, it treat that pointer as char * and read input and store the result to given location. When printing it later, it prints the string value.
What's happening in Case II:
The type of dynamicArray is char *.
The type of &dynamicArray is char **.
So, you are passing char ** type to scanf() which expects char * when %s format specifier is used. Hence compiler is giving warning on this statement.
The pointer &dynamicArray is different from dynamicArray.
Consider this example:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char* dynamicArray;
dynamicArray = malloc(sizeof(char)*100);
if (dynamicArray == NULL) {
exit(EXIT_FAILURE);
}
printf ("dynamicArray: %p\n", (void*)dynamicArray);
printf ("&dynamicArray : %p\n", (void*)&dynamicArray);
free(dynamicArray);
return 0;
}
Output:
## ./a.out
dynamicArray: 0x7fd615401690
&dynamicArray : 0x7ffee7ab7ad0
dynamicArray and &dynamicArray both yield different pointer.
When you pass &dynamicArray to scanf() (which read input and store the result to given location), it lead to undefined behavior2) because your program end up accessing invalid memory.
When you pass &dynamicArray to printf() with format specifier %s, printf(), it access that address to write the character string and end up accessing invalid memory, lead to undefined behavior2). Hence, you are getting segfault.
1) An array is automatically converted to a pointer to its first element but there are few exceptions to this rule (C11 Standards#6.3.2.1p3):
- The array is the operand of
sizeof operator.
- The array is the operand of
_Alignof operator.
- The array is the operand of
&.
- The array is a string literal used to initialize an array.
2) An undefined behavior includes it may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended.
dynamicArraywhich is already a pointer. Removing the&will fix the warning.scanf. It wants achar *but you passed achar (*)[100]instead. Exactly as it told you. Fix it by removing the&, i.e.scanf("%s", staticArray);Remember, C arrays "decay" into pointers in many contexts, including being passed as function arguments.