если это плохая идея, как выделить память в функции?
Почему память malloc в функции и свобода снаружи - плохая идея?
Ответ 1
Это не "плохая идея", а скорее "иногда плохая идея", что можно сказать о многих идеях в программировании.
Выделение памяти внутри функции и ее выпуск снаружи может быть общим шаблоном проектирования. Рассмотрим:
// hashtable is a typedef-ed pointer type
hashtable ht = hashtable_new();
// .. do something with hashtable
hashtable_free(ht);
ht
был выделен в функции hashtable_new
и выпущен за его пределами, но вы увидите этот шаблон снова и снова в большом количестве хорошего кода C.
Тем не менее, он показывает, как одна и та же логическая единица (хэш-таблица ADT) заботится о распределении и де-распределении. Это имеет большой смысл - потому что тот, кто знает, как распределить, лучше знает, как освободить. Выделение и освобождение в разных логических единицах чаще всего представляет собой плохую идею.
Ответ 2
Этот вопрос легче всего ответить, если мы его отменим:
- Почему это может быть хорошей идеей, если каждый объект
malloc
'd в функции такжеfree
d в той же функции?
Ответ: не будет утечек памяти или оборванных указателей, и этот ценный результат достигается без сотрудничества с любой другой функцией. В результате, легче получить код вправо, а функция имеет простой интерфейс.
Теперь, что, если функция вызывает malloc
, но не free
? Затем должны быть правила о том, кто обязан освобождать память, когда это разрешено делать, и когда это необходимо сделать. Эти правила становятся частью функционального интерфейса, и любой, кто вызывает эту функцию, должен либо следить за тем, чтобы соблюдались правила или следовали, либо, возможно, накладывал аналогичные правила на своих вызывающих абонентов и т.д. Явное управление памятью добавляет сложности интерфейсам, и чем сложнее интерфейсы, тем легче сделать ошибку, которая приводит к ошибке памяти и m, а в C ошибка памяти может привести к сбою вашей программы.
К сожалению, иногда необходимо иметь объект, который (a) должен быть назначен во время выполнения, и (b) должен пережить активацию функции, которая его выделяет. В таких случаях, хотя кажется, что это может быть плохой идеей, у нас нет выбора, кроме как выполнить выделение, усложнить интерфейс и потребовать, чтобы вызывающий пользователь правильно управлял объектом.
(Один из самых простых случаев - это когда объект выделяется во время выполнения, но ему разрешено жить вечно, но вы должны связать количество таких объектов или у вас не хватит места.)
Ответ 3
Не обязательно плохая идея выделить память в функции. Вы просто должны быть уверены, чтобы очистить его соответствующим образом.
Проблема заключается в том, что вы можете потерять возможность сделать это, как только вы покинете область действия.
Просто будьте осторожны с вашим дизайном. Сопоставьте malloc со свободным каждый раз, и у вас не будет утечек памяти.
Ответ 4
Неплохая идея, если вы просто сохраните ее в своем собственном стиле.
Хорошим подходом является передача выделенной памяти вызывающей стороне, которая затем может ее освободить, когда она будет выполнена. Что-то вроде этого:
int my_new(char **obj) {
*obj = malloc(somesize);
}
а затем вызовите это из вашей функции следующим образом:
char *obj;
my_new(&obj);
/* work on obj */
free(obj)
Изменить: сделано my_new()
return int
. Нет необходимости в двойных указателях в противном случае