2013-02-12 2 views
-1

Я пытался выполнить следующий код на Linux, установленном на рабочем столе, а также тот же Linux, установленный на виртуальной машине.результат ошибки сегментации

#include <stdio.h> 

int main() 
{ 
    int *ptr; 
    printf("%d\n",*ptr); 
    return 0; 
} 

Я был удивлен, чтобы увидеть результаты на Linux, установленный непосредственно на рабочем столе она дает «сбой сегментации» , тогда как на Linux, установленный на виртуальной машине, он печатает некоторое значение вредного. Может кто-нибудь, пожалуйста, помогите мне понять, почему это так?

+1

Исправить ошибку, и тайна исчезнет. Багги код гораздо сложнее понять, чем правильный код. –

+1

Это называется «неопределенным поведением». Вы не можете сказать, что он может сделать. – ugoren

+1

Вызов неинициализированного указателя - это неопределенное поведение. «Undefined» означает, что все может случиться. Вы можете получить ошибку сегментации. Или значение может быть мусором. Или ваш компьютер может взорваться. Все идет. –

ответ

1

Ваш указатель не инициализирован. Инициализировать его, как показано ниже:

int a = 42; 
int *ptr = &a; 

Разыменования Беспоставочного инициализируются указатель вызывающего неопределенного поведения, ваш printf вызова может напечатать какой-то мусор или просто сбой.

Могу ли я предложить вам прочитать книгу о программировании на С?

+0

Я знаю, что мы должны инициализировать указатель, так как это память не с управлением программой. Он может или не указывать на карту памяти программы, поэтому поведение будет неопределенным. Меня беспокоит, почему он не дает ошибки сегментации на виртуальной машине. Я попытался скомпилировать и запустить его 100 раз, но он всегда давал нежелательную ценность. Я бы, по крайней мере, дал бы сегментированную ошибку хотя бы один раз, когда я, возможно, не разместил этот вопрос. Не могли бы вы сказать, что это связано с виртуальной машиной. Может быть? – sandy

1

Потому что вы имеете дело с "НЕОПРЕДЕЛЕННЫМ ПОВЕДЕНИЕМ". То, что происходит, не определяется. Он может упасть, он может сгореть, или он может сделать что-то еще ожидаемое или неожиданное.

В этом конкретном случае это, вероятно, связано со значением, которое ptr получает от стека - на виртуальной машине будет иметь действительный адрес памяти, поэтому вы получите некоторые случайные бит памяти, которые вы не знаете что это. На не виртуальной машине значение отличается [или память находится по-разному], и вы получаете ошибку seg для доступа к недопустимой ячейке памяти.

НИЧЕГО НЕОБХОДИМО получить доступ к указателю, который не был настроен ни на что, но от него не гарантируется сбой. Он может точно также печатать все, что находится на этом адресе памяти.

+0

ya, но он всегда дает некоторое значение, которое будет постоянным, но адрес, на который указывает, изменяется для каждого прогона. Есть ли вероятность, что любая неинициализированная память в виртуальной машине содержит определенное значение. Я знаю, что это может быть неверно, но просто спросили, как вопрос любопытства. – sandy

+0

Виртуальная машина должна вести себя точно так же, как и на самой простой системе. Но могут быть различия в том, где вещи в конечном итоге оказываются в памяти по ряду причин. И нет, это не обязательно одно и то же - либо современные ОС имеют «рандомизацию адресного пространства», которая перемещает вещи в памяти из одного пробега в другой. –

1

У вас есть неинициализированный указатель. Указатель как целое с адресом, на который указывает. Поскольку он не инициализирован, он может содержать любое значение. Таким образом, на вашем VPS может указываться некоторый действительный адрес, к которому ваш процесс может получить доступ, и на вашем компьютере он указывает на то, что неизвестно, что доступ к процессу невозможен.

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