0

I'm working on an easy project but I've encountered an error. I'm coding in Unix and executing the code with the terminal.

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int atis;
    char *weather;

    //Création du fichier ATIS
    if((atis = creat("atis", 0666)) == -1)
    {
        printf("Error while creating the ATIS file\n");
        exit(-1);
    }

    //Ouverture du fichier ATIS
    if((atis = open("atis", 0666)) == -1)
    {
        printf("Permission denied\n");
        exit(-1);
    }

    //Mise à jour du fichier ATIS
    printf("OK or KO for a take-off? ");
    gets(weather);
    if(write(atis, weather, sizeof(weather))==-1)
    {
        printf("Write error\n");
        exit(-1);
    }


    close(atis);
    return 0;
}**

The error is a segmentation fault 11.

Thank you in advance! (and sorry for my English, it's really bad ^^)

Mike
  • 47,263
  • 29
  • 113
  • 177
  • 2
    [Debug](http://gcc.gnu.org/bugs/segfault.html) your code – Joe Jan 15 '13 at 14:56
  • _"OK or KO for a take-off?"_ - What airport is this and how can I avoid it? – Sean Bright Jan 15 '13 at 14:57
  • Did you intend `0666` to be an octal number equivalent to 438 decimal or 1B6 hex? Because that is what it is, leading zero in an integer literal means octal format in C, just like 0x means hex format. – Lundin Jan 15 '13 at 15:46
  • @Lundin file permissions are octal so the example should be correct. – Joe Jan 15 '13 at 16:41

5 Answers5

5

weather is an unitialized char* when first used at the following call:

gets(weather);

meaning gets() will be attempting to write to memory it should not, causing the segmentation fault. Allocate memory for weather or use an array:

char weather[128];

In the subsequent call to write() use strlen(weather) instead of sizeof(weather) to only write the characters that were read (and to correctly handle the case where weather is a char* and not a char[]).

Additionally, see Why is the gets function so dangerous that it should not be used?. Use fgets() or possibly scanf() with length specifier instead.

Community
  • 1
  • 1
hmjd
  • 120,187
  • 20
  • 207
  • 252
2

You never assign any memory to your pointer: char *weather;

From the man page:

char *gets(char *s);
gets() reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF,

So you need a buffer to store it into:

char weather[10];

or

char *weather;
weather = malloc(10);

would do it if 10 is sufficient. That leads to the other point, again, from the man page:

Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead.

ex:

fgets (weather, 10 , stdin);
Mike
  • 47,263
  • 29
  • 113
  • 177
2

The problem is these two lines:

char *weather;

and

gets(weather);

The first declares weather to be a pointer, but it's left uninitialized (i.e. points to a seemingly random location). The second line writes to what weather points to, which means you write to some random location.

Declare weather as an array, and use fgets instead:

char weather[64];

/* ... */

fgets(weather, sizeof(weather), stdin);
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

You do gets(weather) on a pointer that doesn't point to allocated memory.

matekm
  • 5,990
  • 3
  • 26
  • 31
0
char *weather;

and then

gets(weather);

that cause a segmentation fault. the weather should be pointed to a memory space:

  • staic

    char weather[100]

  • or dynamic

    char *weather = malloc(100*sizeof(char));

MOHAMED
  • 41,599
  • 58
  • 163
  • 268
  • `sizeof(char)` always will be 1, so it's unneeded. – Mike Jan 15 '13 at 15:04
  • @Mike Not really, it says "I know what I'm doing", unlike `malloc(100)` without any comment, that just says "I may know what I'm doing, or I may have made a fatal bug here". But then again, `malloc(MY_CONST)` might be the best form, since "magic numbers" should always be avoided. – Lundin Jan 15 '13 at 15:51