Синтаксический запрос указателя - PullRequest
0 голосов
/ 28 января 2012

Кажется, я не могу понять разницу между приведенным ниже обозначением указателя. Может, кто-нибудь мне подскажет?

 typedef struct some_struct struct_name;
  struct_name this;
  char buf[50];
  this = *((some_struct *)(buf));

Теперь я попытался немного поиграть и сделал следующее:1004 *

  struct some_struct * this;
     char buf[50];
     this=(struct some_struct *)buf; 

Что касается меня, я думаю, что обе реализации должны давать один и тот же результат. Может ли кто-нибудь подсказать мне, есть ли разница между этими двумя, и если да, может кто-нибудь это указать?

Спасибо.

Ответы [ 3 ]

3 голосов
/ 28 января 2012

В вашем первом фрагменте this - это не указатель, а экземпляр some_struct.Сделанное вами назначение сделало поверхностную копию (т.е. memcpy()) того, что находится в buf, как если бы это был также экземпляр some_struct.

Во втором фрагменте this - указатель, ион просто указывает на адрес buf.

Итак, чтобы подвести итог, первый фрагмент this не является указателем, и структура копируется в него.Во втором это указатель и он назначен той же памяти, что и buf (т.е. не копия).

0 голосов
/ 28 января 2012

У обоих подходов есть свои проблемы.

  • выравнивание: ваш buf может быть неправильно выровнен для переменной типа структуры. Если это так, то это приведет к неопределенному поведению (UB): в лучшем случае оно прерывает вашу программу, но может привести к гораздо худшим последствиям.
  • инициализация: в первых случаях вы получаете доступ к неинициализированной памяти для чтения. В лучшем случае это дает вам неопределенные данные, то есть случайные байты. В худшем случае char - это целочисленный тип со знаком на вашей платформе, и вы попали в ловушку для char => UB, как указано выше. (Ваш второй случай столкнется с той же проблемой, когда вы попытаетесь получить доступ к объекту на другом конце указателя.)

Как избежать всего этого:

  • Всегда инициализируйте ваши переменные. Простой = { 0 } должен делать во всех случаях.
  • никогда не используйте char в качестве универсального типа для байтов, но используйте unsigned char
  • никогда не приводит байтовый буфер произвольного выравнивания к другому типу данных. При необходимости сделайте все наоборот, приведите объект struct к unsigned char.
0 голосов
/ 28 января 2012

Во втором «this» будет указывать на первую ячейку памяти «buf». В первом примере вы либо получите ошибку компилятора (я не думаю, что вы можете назначить структуры в C с =, хотя я могу ошибаться), либо будет скопировано содержимое buf (вплоть до sizeof (struct_name)) в это, который находится в стеке.

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