2016-09-05 3 views
1

У меня есть некоторые похожие вопросы к этому, однако я спрашиваю очень прямо, так что, надеюсь, я могу получить хорошее объяснение того, что, черт возьми, происходит ,C - fgets загадочно вызывает segfault при использовании char arrays

Посмотрите на это очень простая программа:

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; 
}; 

Как вы можете видеть, раздел «а» работает нормально. однако разрывы раздела 'b' seg. Что происходит?

+0

'a [200];' вызывает [неопределенное поведение] (http://stackoverflow.com/a/4105123/1505939) –

+3

Нет тайны об этом. Это неспособность изучить базовый C, это проблема. 'char * a; a [200]; '->' char a [200] 'и' char * b; b [200]; '->' char b [200] ' – kaylum

+0

@ M.M Но почему это неопределенное поведение? –

ответ

2

Хорошо, это основы здесь. Segfault означает, что вы используете память, к которой у вас нет доступа.

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; 
}; 

В зависимости от многих вещей иногда это может терпеть неудачу, а иногда и нет. Но вы делаете что-то неправильно здесь. У вас есть способ исправить это. Во-первых, используя простой массив символов

#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); 
} 

Или, если вы хотите продолжать использовать указатели

#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)); 
} 

Но в любом случае, ваши результаты ошибка из-за отсутствия знаний о указкой и памяти в C.

Удачи вам в этом,

+3

Если код будет использовать' malloc() ', он должен строго проверить возвращаемое значение перед использованием Это. Вызов 'write()' является загадочным - записывает неинициализированные данные, которые 'malloc()' предоставляет для стандартного вывода. Вероятно, это лучше всего удалить или изменить на 'memset()'. –

+0

@JonathanLeffler, вы правы, но никакая программа не потерпит неудачу, выполнив 'malloc (200);' :) –

Смежные вопросы