0

This code compiles with a warning but prints the input string:

char staticArray[100];
scanf("%s",&staticArray);
printf("%s\n", staticArray);

Warning: format specifies type 'char *' but the argument has type 'char (*)[100]' [-Wformat]

This code also compiles with a warning but throws segmentation fault:

char* dynamicArray;
dynamicArray = (char*) malloc(sizeof(char)*100);
scanf("%s", &dynamicArray);
printf("%s\n", dynamicArray);

Warning: format specifies type 'char *' but the argument has type 'char **' [-Wformat]

I know both are wrong but, why does the first one prints the string value?

2
  • For the warning in the second example, the issue is that you are getting the pointer of dynamicArray which is already a pointer. Removing the & will fix the warning. Commented Apr 18, 2020 at 3:03
  • The warning is because you passed the wrong type toscanf. It wants a char * but you passed a char (*)[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. Commented Apr 18, 2020 at 3:14

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

Comments

1

Removing the & operator in both examples will solve the warnings. I'm not sure what your intended behavior is, but they seem to work correctly upon moving the & operator. This is because arrays are inherently pointers to the first element of the array so adding & is not what you want.

Working examples(exactly the same expect for &):

char staticArray[100];
scanf("%s",staticArray);
printf("%s\n", staticArray);

and

char* dynamicArray;
dynamicArray = (char*) malloc(sizeof(char)*100);
scanf("%s", dynamicArray);
printf("%s\n", dynamicArray);

1 Comment

Thanks, I know it works correctly without the & operator. I was asking for the different behavior when passing a pointer to a static array. I was expecting a segmentation fault but it printed some value. H.S. answer explains why.

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.