2016-11-16 14 views
0

Я и мой друг используют структуры в нашем коде (наш код отделен друг от друга). Давайте возьмем следующий пример:Использование указателей или ссылок на struct

struct Book { 
    char title; 
    int pages; 
} 

void setBook(struct Book *tempBook) { 
    tempBook->title = "NiceTitle"; 
    tempBook->pages = 50; 
} 

Приведенный выше код довольно прямолинейный. Дело в том, есть ли какая-то разница в том, эти две сети:

int main() { 
    struct book obj1; 
    setBook(&obj); 
    } 

Или

int main() { 
    struct Book *obj2; 
    setBook(obj2); 
} 

EDIT: не было ясно, в своем заявлении. Я инициализируется Пинтера в

struct Book *obj2 = malloc(sizeof(struct obj2)); 
+4

В первом фрагменте: 'char title;' -> 'char * title;' –

+3

Да, есть разница. Один будет работать, и никто не будет работать. –

+0

@SamVarshavchik можно работать * – George

ответ

6

В случае

struct book obj1; 
setBook(&obj); 

вы передаете правильный адрес # 1 функции, поэтому поведение определяется.

С другой стороны,

struct Book *obj2; 
setBook(obj2); 

вы пропускание инициализирован указателем # 2, доступом к которой вызывающей undefined behavior.

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


# 1 - obj1 автоматическая локальная переменная, и адрес этой переменной является действительным адресом в области.

# 2 - struct Book *obj2; определяет указатель и снова obj2 является автоматической локальной переменной, он не является неявным образом инициализированным ни к чему. Таким образом, начальное значение (то есть адрес памяти, на котором указывает указатель) является неопределенным и довольно хорошо недействительным.

+0

Допустим, я инициализировал указатель на адрес, иначе будет ли разница? –

+0

@ EmilMøllerRinggaard Что такое «адрес»? это _valid_? Откуда вы знаете? –

+0

Это на микропроцессоре, и он компилируется, поэтому я думаю, что он работает –

4
struct Book *obj2; 

в main это просто указатель с неопределенным значением. Он не указывает на то, что вы выделили. Вы можете разыменовать его, но это неопределенное поведение.

struct Book obj1; 

выделяет struct Book. Вы можете использовать его адрес и изменить его членов.


Примечания:

  • title из struct Book является char, который может содержать только один символ, а не строка (то есть указатель). Используйте вместо этого char * или const char *.
0

В первом случае вы передаете переменную типа «struct Book» в функцию setBook. Так как вы объявили переменную, то общая память занята obj1 -s sizeof (setBook), то есть sizeof (char) + sizeof (int), которая равна 5 байтам. следовательно, вы можете получить доступ как obj1 .title (1 байт) и obj1.pages (4 байта).

ПРИМЕЧАНИЕ: - Предполагая, что int составляет 4 байта.

Посмотрим, что произойдет во втором сценарии.

struct Book * obj2; obj2 размер id 4 байта, поскольку он является общим указателем. Поле также не делится и, следовательно, мы не можем получить доступ к полю.

Следовательно, Во втором случае вам нужно выделить динамически, прежде чем пытаться использовать члены. При распределении будет задано правильное и правильно разделенное поле.

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

  • Нет связанных вопросов^_^