1

I've seem some similar questions to this one, however I'm asking in a very direct way so hopefully I can get a good explanation as to what the hell is going on.

Look at this very simple program:

int main()
{
    char* a;
    a[200];
    fgets(a, 200, stdin);

    char* b;
    b[200];
    fgets(b, 200, stdin); // Seg fault occurs once I press enter

    return 0;
};

As you can see, section 'a' runs fine. however section 'b' seg faults. What is going on?

Dellowar
  • 3,160
  • 1
  • 18
  • 37
  • `a[200];` causes [undefined behaviour](http://stackoverflow.com/a/4105123/1505939) – M.M Sep 05 '16 at 03:38
  • 3
    No mystery about it. It's failing to learn basic C that is the problem. `char* a; a[200];` --> `char a[200]` and `char* b; b[200];` --> `char b[200]` – kaylum Sep 05 '16 at 03:40
  • @M.M But why is it undefined behaviour? – Dellowar Sep 05 '16 at 03:58
  • @SanchkeDellowar: It is undefined behaviour because the variable `a` is a `char *` (that's what `char *a;` means). There's no initializer for the pointer, so any dereference of the pointer leads to UB (undefined behaviour). The `a[200];` dereferences the uninitialized pointer; fortunately for you, the compiler probably optimizes that away. You need `char a[200];` to be in the realm of defined behaviour (and similarly for `b`). The call to `fgets()` is equally UB. You're unlucky that the code didn't crash sooner, but undefined behaviour is funny stuff — anything can happen and it is OK! – Jonathan Leffler Sep 05 '16 at 04:03
  • @SanchkeDellowar `a` does not point anywhere, so you cannot dereference it (i.e. look up the memory where it is pointing to) – M.M Sep 05 '16 at 04:09

1 Answers1

2

Well, this is basics here. A segfault means you are using memory you do not have access to it.

int main()
{
    char* a; // Create a pointer (a pointer can only contains an address (int size)
    a[200]; // Trying to access to the byt 200 of your pointer but basicaly do nothing. You are suppose to have a segfault here

    fgets(a, 200, stdin); // store your stdin into &a (you may have a segfault here too)

    return 0;
};

Depending on many thing, sometimes it may fails, sometimes not. But you are doing something wrong here. You have to way to fix this. First using a simple array char

#include <stdio.h> /* for stdin */
#include <stdlib.h> /* for malloc(3) */
#include <string.h> /* for strlen(3) */
#include <unistd.h> /* for write(2) */

int main()
{
     char str[200];
     fgets(str, sizeof str, stdin);

     write(1, str, strlen(str)); /* you can receive less than the 200 chars */

     return (0);
}

Or if you want to keep using pointers

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main()
{
     const size_t sz = 200;
     char* str;
     str = malloc(sz);

     fgets(str, sz, stdin);

     write(1, str, strlen(str));
}

But anyway, your mistake results from a lack of knowledge about pointer and memory in C.

Good luck with that,

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31
Dlacreme
  • 196
  • 1
  • 8
  • 3
    If the code's going to use `malloc()`, it should strictly check the return value before using it. The call to `write()` is mysterious — that writes the uninitialized data that `malloc()` provides to standard output. It is probably best deleted, or changed to `memset()`. – Jonathan Leffler Sep 05 '16 at 04:08
  • @JonathanLeffler, you're right, but no program is going to fail by doing a `malloc(200);` :) – Luis Colorado Sep 05 '16 at 09:16