Присвоение значения указателю приводит к ошибке - PullRequest
0 голосов
/ 29 марта 2020

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

int main()
{
  int i=3, *p;
  p = &i+1;
  *p = 30;
  printf(“%d”, *p);
 } 

, если я использую этот код, он работает нормально.

int main()
    {
      int i=3, *p, *q;
      q = &i;
      p = q+1;
      *p = 30;
      printf(“%d”, *p);
     } 

Спасибо за ваш ответ

Ответы [ 2 ]

0 голосов
/ 29 марта 2020

@ У Олафа Дитше был очень хороший ответ, но так как вы задали вопрос с помощью данного кода, я предполагаю, что вы не совсем понимаете основы указателей и оператора &.

Позвольте мне начать с вашего пример, где у вас есть переменная 'int' и указатель на нее:

int a = 10;
int* p = &a;

Что этот код делает, это объявляет локальную переменную типа int, а затем объявляет другую переменную типа int*. Затем указатель инициализируется с адресом a с использованием оператора &.

Теперь вы должны понимать, что каждая переменная хранится по своему адресу и имеет некоторое значение. Это означает, что переменная var хранится по адресу &var и имеет значение того, что хранится в битах по адресу &var. Это относится ко всем переменным, включая указатели!

В приведенном выше примере переменная a хранится по адресу &a и имеет значение 10. Указатель p хранится по адресу &p и имеет значение &a.

Если вы собираетесь использовать такие указатели, вы должны узнать о области действия и времени жизни локальных переменных. Например, в приведенной ниже функции var является локальной переменной. Он размещается в стеке только тогда, когда функция выполняется, и после этого она извлекается.

void f()
{
    int var = 10;
    var = var + 5;
} // <-- scope of the function is exited. var is popped from the stack.

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

int main()
{
    int* p;

    // now we create a scope
    {
        int a = 10;
        p = &a;
    }

    // this is undefined behaviour.
    printf("%d", *p);

    return 0;
}

Даже если код будет скомпилирован и запущен без ошибок, это не правильно. Если вы запустите его, ничто не будет гарантировать, что будет вывод, потому что адрес a был освобожден при выходе из области и будет использоваться для хранения других вещей в стеке.

Почему ваш первый пример cra sh? @ Олаф Дитче объяснил это в своем ответе.

Почему ваш второй пример не подходит sh? Это похоже на мой последний пример. Он будет скомпилирован и запущен, но у вас нет никаких гарантий относительно того, что произойдет.

0 голосов
/ 29 марта 2020

Вы должны выделить c памяти для p, иначе вы получите случайные результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...