В чем проблема с int * p; * Р = 23; - PullRequest
15 голосов
/ 29 марта 2010

Вчера в моем интервью мне задавали этот вопрос. (В то время я находился под большим количеством резких вопросов).

int *p;
*p=23;
printf("%d",*p);

Есть ли проблемы с этим кодом?

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

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

EDIT Я добавил код на листе; -

int *p;
p=malloc(sizeof(int));
*p=23;
printf("%d",*p);      

Это должно быть идеальный код ... Я прав ..

EDIT2

int *p;
*p=23;
 OR
int *p=23;

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

Ответы [ 7 ]

28 голосов
/ 29 марта 2010

"пытается присвоить значение указателю, которому не выделена память"

Я думаю, вы просто немного перефразировали это. Вы не пытаетесь присвоить значение указателю, вы пытаетесь присвоить значение ссылке и указателя.

Поскольку указатель не инициализирован, это, как вы говорите, неопределенное поведение. Указатель ни на что не ссылается (по крайней мере, неверно - как указывают другие ответы, биты памяти p могут содержать значение, являющееся адресом некоторой области памяти, и ваш код может перезаписываться Стандарт разрешает все, что происходит с UB, но, зная кое-что о вашей реализации, вы часто можете сделать хитрое предположение).

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

14 голосов
/ 29 марта 2010

p не инициализируется - в нем хранится некоторый адрес . Разыменование это неопределенное поведение.

Адрес, сохраненный в p, может отображаться в адресное пространство процесса или может не отображаться. Если это сопоставлено, некоторые несвязанные (но, возможно, важные для программы) данные сохраняются по этому адресу. Таким образом, либо ваша программа аварийно завершает работу из-за защиты памяти, либо вы изменяете некоторые данные, принадлежащие программе. Последствия последнего могут различаться - может быть, ничего не происходит, может быть, вы не замечаете, может быть, вы повредили важные данные, и программа разваливается - классическое неопределенное поведение.

7 голосов
/ 29 марта 2010

'p' указывает на неизвестное местоположение, а не на "не выделенную" память.

Разница в том, что, поскольку он не определен, он может указывать на выделенную память, даже если эта память не предназначена для доступа этой функцией.

3 голосов
/ 29 марта 2010

int * p = 23;

Это совершенно другое. Здесь вы объявляете указатель и присваиваете ему значение 23. Это означает, что теперь он указывает на область памяти 23, которая может содержать или не содержать читаемые данные.

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

3 голосов
/ 29 марта 2010
#include <stdio.h>
#include <stdlib.h>

int main(char** argv) {
  // THIS POINTER IS NOT DECLARED (SO IT'S NOT USABLE/INVALID)
  int *p;
  // 1) SO RESERVE MEMORY AND SET POINTER TO VALID MEMORY...
  p=malloc(sizeof(int));
  // 2) ...CHECK IF ALLOCATION WAS OK...
  if (p) {
    *p=23;
    printf("%d",*p);
  } else printf("sorry, no memory");
  // 3) ...AND FINALLY DE-ALLOCATE MEMORY (FREEING IS IGNORED WHEN p IS NULL)!
  free(p);
}
2 голосов
/ 29 марта 2010

int * p;

initailly вышеупомянутый указатель содержит некоторое значение мусора (неверное значение адреса или нераспределенный адрес).

* р = 23;

тогда вы пытаетесь поместить какое-то значение (23) в недействительную память, что приводит к неопределенному поведению.

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

Помимо того факта, что в примере не выделяется память для значения 23, он также не будет компилироваться в первую очередь, поскольку у вас есть два символа в вашей характерной константе (которая должна быть строкой) , Например, замените «% d» на «% d» в выражении printf.

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