2016-01-21 3 views
-1

Я пишу простую программу в c и я застрял с этой ошибкойЗастрял с ошибкой Segmentation Fault

Segmentation Fault (основные сбрасывали)

Я знаю, что происходит Segmentation fault ошибки из-за нарушения доступа к памяти. Но я не могу понять, где в следующей простой программе происходит плохой доступ к памяти.

#include<stdio.h> 
int main() 
{ 
    int a = 0; 
    scanf("%d", a); 
    printf("%d\n", a); 
    return(0); 
} 

Я компиляция онлайн here, в блоках кода и это дает ту же ошибку.

+0

Проблема заключается в зсапЕ, как указывалось другими, но я не уверен, о возврате либо. –

+2

@ClaudioCortese 'return (0)' действителен, но не нужен, просто 'return 0' будет делать. –

+0

@Weather Wane, не знал, что, LSNED;) –

ответ

4

Необходимо ввести указатель на int вместо int. Измените его на

if (scanf("%d", &a) == 1) 
    printf("%d\n", a); 
else 
    printf("Invalid input\n"); 

В коде scanf() при условии, что значение в int является адресом он должен написать, что приводит к непредсказуемому поведению . Кроме того, другая причина неопределенного поведения заключается в том, что a не инициализирован до вызова scanf(), но это не имеет значения, так как в любом случае не определено поведение. Стандарт указывает, что любой параметр неожиданного типа, переданный в scanf(), вызывает неопределенное поведение.

Тот факт, что a не была инициализирована перед вызовом scanf() следует, что если игнорировать возвращаемое значение scanf() и это не удается, и вы пытаетесь прочитать a как в printf() в коде, ваш код будет вызывать неопределенное поведение , Вот почему так важно проверить возвращаемое значение.

&адрес оператора делает указатель, содержащий адрес это операнд, scanf() нужен указатель параметр для того, чтобы иметь возможность сохранять результат в нем.

Обратите внимание, что при прохождении массива например, char массив scanf() строку с "%s" спецификатором, вы не должны использовать оператор &, так как имя массива преобразуется в poitner первый элемент сам по себе, что что в этом случае нуждается scanf().


Обратите внимание, что нет проходят по ссылке в , так что это единственный способ, вы можете изменить параметр внутри функции scanf().

+0

К сожалению, это происходит, когда вы переходите на другой язык программирования. Из последних нескольких месяцев я кодирую в Python, что приводит к этому :) – Atinesh

+2

@Atinesh Нет, это то, что происходит, когда вы не читаете внимательно документацию о функциях, которые вы используете. Если вы читаете ['scanf()'] (http://man7.org/linux/man-pages/man3/scanf.3.html), вы также поймете, почему я сравниваю его возвращаемое значение с '1'. И всегда, игнорирование возвращаемого значения может привести к очень странным ошибкам. –

+1

PS, следует заметить, что int фактически считывается 'scanf' как адрес памяти (как если бы он был действительным указателем), так что результат записывается в память с адресом, который == VALUE' a' вместо памяти, принадлежащей 'a'. – Myst

4

Изменить

scanf("%d", a); 

в

scanf("%d", &a); 

scanf нужен указатель переменной, а не значение переменной.

Я могу предложить вам добавить -Wall вариант при компиляции. В вашем случае НКУ предупредит вас:

test.c: In function ‘main’: 
test.c:25:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=] 
    scanf("%d", a); 
    ^