Allepta
@Allepta

В чем разница между указателями в си?

Приветствую, не могу самостоятельно разобраться в чем разница между двумя методами использования, к примеру:
obj.show_name и obj->show_name

Допустим имеем структуру данных:
typedef struct users
{ 
  char* name;
  char* password;
}user_t;

Далее начинаем работать с этой структурой:
user_t mt1;
user_t *mt2;

int main()
{
  mt1.name = "Andrey";
  mt1.password = "Password";

  mt2 = malloc(sizeof(user_t));
  mt2->name = strdup("Andrey");
  mt2->password = strdup("Password");

  mt1.name = NULL;
  mt2.password = NULL;

  free(mt2->name);
  free(mt2->password);

  return 0;
}

В каких случаях нужно использовать mt1, а в каких mt2? На мой взгляд разницы в их работе нет, в то время как реализация mt1 явно короче чем mt2, опираясь на этот факт, я почти всегда использую метод mt1 и не понимаю зачем использовать mt2.

Пробовал найти ответ в литературе (С. Прата), теория понятна, но на практике не могу понять принципиальные различия этих двух подходов.
  • Вопрос задан
  • 190 просмотров
Пригласить эксперта
Ответы на вопрос 3
vt4a2h
@vt4a2h
Senior software engineer (C++/Qt/boost)
Есть понятие стека. Стек небольшого размера: на нём большие объекты лучше не выделять. Поэтому необходима ещё и куча -- там выделяют память с помощью malloc.

Помимо этого, в первом и втором случае различается время жизни объектов. Объект, выделенный на стеке живёт до конца области видимости (до закрывающейся фигурной скобки обычно). Объект выделенный в куче живёт пока его явно не удалят (с помощью метода free, который вы забыли вызвать). Т.е. такие динамически выделенные объекты ещё и удобны, если вам надо передать сам объект и/или управление его временем жизни в другую часть программы.

Ну и если вы хотите модифицировать любой объект (не важно как созданный) в какой-то сторонней функции, то вам надо передать указатель на этот объект. Насколько я помню, в C ссылок нет.

PS
По C лучше K&R читайте.
Ответ написан
Комментировать
@rPman
Есть еще символ & который позволяет описывать переменные, доступ к которым синтаксически ничем не отличается от прямого доступа но по факту это ссылка:
class MyClass
{
public int value;
MyClass(int _value):value(_value){}
}

MyClass *tmp=new MyClass(10);
MyClass &object=*tmp;
object.value=20;
delete(tmp);

99% различий кроются в способах инициализации (и освобождении памяти), и в последние 10 лет в c++ наплодили столько изменений именно вокруг этого.

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

p.s. используйте & для определения типов параметров передаваемых в функции, чтобы происходило не копирование а передача по ссылке, и при этом синтаксически вы бы работали с объектами напрямую.
Ответ написан
Комментировать
CityCat4
@CityCat4 Куратор тега C
//COPY01 EXEC PGM=IEBGENER
Все просто.
Попробуйте-как динамически память выделить, используя только mt1 :) (Хинт: не получится нифига. Выделить память через malloc еще можно, используя sizeof struct, а вот присвоить адрес начала области переменной mt1 фиг получится)
Структуры - офигенное средство для расписывания памяти, особенно при чтении бинарных файлов фиксированной структуры внутри - считал N байт в область, наложил на эту область структуру - и все, можно к полям обращаться. Что, собственно в примере у Вас и делается.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы