Доступ к указателю через вложенную структуру - PullRequest
1 голос
/ 16 сентября 2011
struct x {
  int *u;
};

struct y {
  struct x *z;
};

int main()
{
  static y b;
  static int g=7;
  b.z->u=&g;
}

Оператор b.z->u=&g дает ошибку сегментации. Если я уберу static перед int g:

int g=7;
b.z->u=&g;  

Код выполняется правильно.

Ответы [ 4 ]

2 голосов
/ 16 сентября 2011

b.z еще не инициализирован.Вы инициализируете b с помощью:

static y b;

, но его поле члена z все еще является нулевым указателем (указывающим на какое-то случайное местоположение).Так что доступ к его члену u приводит к ошибке сегментации при доступе к некоторой случайной памяти.

Я полагаю, что это должно работать (не пытался):

static y b;
static x c;
static int g=7;
b.z = &c;
b.z->u=&g;

Почему вашВторой пример работает, я не знаю.Я подозреваю, что это из-за «удачи» ...

2 голосов
/ 16 сентября 2011

Поскольку b.z не был установлен, чтобы указать где-либо полезное. В настоящее время это просто указатель NULL. *

Вам нужно сделать что-то вроде:

b.z = malloc(sizeof(*b.z));

сначала (т.е. создать реальный объект).

Не забудьте free это в какой-то момент.

<ч />

* Обратите внимание, что это только NULL, поскольку b объявлено как static. Если бы b не было static, оно указывало бы на случайное место в памяти.

1 голос
/ 16 сентября 2011

Вы никогда не выделяли память для вашего b.z. Ваш b.z содержит значение неинициализированного мусора, поэтому попытка разыменования b.zb.z->u) вызывает ошибку сегментации.

P.S. Вы объявили свои объекты static, что означает, что b.z изначально содержит нулевое значение (а не "неинициализированное значение мусора", как я уже говорил выше). Тем не менее разыменование нулевого указателя также не определено.

1 голос
/ 16 сентября 2011

Это даст вам ошибку сегментации, потому что вы делаете неопределенное поведение. Вы получаете доступ к z указателю структуры без его инициализации (то есть без предоставления пространства памяти для указания). Тот факт, что он не выдает ошибку сегментации в случае, если переменная не является статической, не важен, так как весь доступ к неинициализированному указателю неверен.

...