2

I get a segmentation fault when I run the following program.

#include<stdio.h>
int main()

{

    char *a[10] = {"hi", "hello", "how"};
    int i ;
    printf("%s %s %s %s %s\n",a[0],a[1],a[2],a[3],a[4]);
    for (i = 0;i < 10; i++)
        printf("%s\n",a[i]);
    return 0;
}

output

hi hello how (null) (null)

hi

hello

how

Segmentation fault (core dumped)

I have gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) and Linux kernel 3.16.0-34-generic.

I know that all the non initialized array entries get the value 0, so I expect a null at the printf. But it gives segmentation fault.

Strangely when I replaced the printf (“%s\n”,a[i]) with printf(“%s %d\n”,a[i],i) I am able to get null for the unfilled array entry.

In fact a space between %s and \n too is free from segmentation fault.

Can anybody tell me the reason behind this behavior.

dvhh
  • 4,724
  • 27
  • 33
  • just to clarify, the segmentation fault only occurs after that `for` loop correct? If you were to remove the for loop you get no error? – Ashwin Gupta Jul 21 '16 at 05:48
  • 1
    That's funny. I have copied your program exactly and it does not give me a segmentation fault. – iRove Jul 21 '16 at 05:48
  • `null` is not the nul character `'\0'`, thus printf will not recognize it as a (zero-length) string, and you get undefined behaviour. It may print `(null)`, it may crash, it may blow up your computer. –  Jul 21 '16 at 05:49
  • 6
    Don't try to make sense of undefined behavior. It's pointless. – R Sahu Jul 21 '16 at 05:49
  • 3
    See also http://stackoverflow.com/questions/11589342/what-is-the-behavior-of-printing-null-with-printfs-s-specifier –  Jul 21 '16 at 05:50
  • @iRove weird. When I try her code on my C++ (I don't have a plain C compiler) compiler it also throws now errors. I'm on windows using Visual Studio's compiler. – Ashwin Gupta Jul 21 '16 at 05:52
  • This is an undefined behavior. Non initialized array could contain any value, this is implementation and even configuration specific. – Ari0nhh Jul 21 '16 at 05:52
  • @AshwinGupta: See [Evert](http://stackoverflow.com/users/707650/evert)'s comment above. The undefined behavior might very well change depending on your system. The Earth could explode, _literally anything_ could happen ([see here for more](http://stackoverflow.com/a/4105123/4520911)) – iRove Jul 21 '16 at 05:54
  • @iRove yeah thats very interesting. I never knew about this. Learned something new today! – Ashwin Gupta Jul 21 '16 at 05:54
  • 1
    @Ari0nhh It's undefined because `NULL` is passed to `printf()` for the `%s` specifier, but not because the array could contain unknown values... the array *is* initialized (the unspecified values will be `NULL`). – Dmitri Jul 21 '16 at 05:59
  • Reason is puts calling strlen to know the length of the string. Your printf will be replaced by puts by the compiler. If you pass a NULL string to strlen, the program crashes for NULL pointer dereference (with signal SIGSEGV). Check with gdb you can see SIGSEGV by strlen. – NishanthSpShetty Jul 21 '16 at 06:29

1 Answers1

3

depending on your compiler, your second printf will be replaced by a puts

see the assembly result and it seems that your system implementation of puts will crash with NULL as a parameter.

dvhh
  • 4,724
  • 27
  • 33
  • 2
    In addition to this, `printf("%s", NULL);` is undefined behaviour, so the fact that it ever worked is more by coincidental generosity than expectation. That kind of code shouldn't be relied upon... – autistic Jul 21 '16 at 06:37
  • You are certainly pointing the gist of the problem here, I was merely pointing why the two calls could behaved differently. – dvhh Jul 21 '16 at 07:16
  • Indeed. Your answer explained a good example where the generosity is stripped away in favour of optimisations (also coincidental). – autistic Jul 21 '16 at 07:31