Я знаю, что это старый пост, но на самом деле не было исчерпывающего ответа на передовой опыт с точки зрения стиля , который, я думаю, и был тем, чего действительно хотел опер, поэтому вот мой обратите внимание на распределение памяти в Си. Заметьте, я в большей степени человек на С ++, поэтому многие мои мысли исходят из этого отношения.
Часто удобно знать, выделен ли ваш указатель, поэтому всегда присваивайте NULL указателю, когда вы его объявляете. Вы также можете создать безопасную свободную функцию, которая освобождает память, а затем присваивает ей значение NULL, чтобы вам не пришлось беспокоиться.
Если вы выделяете память в одном C-файле, вы должны освободить ее в том же файле. Возможно, это более ограничительно, чем необходимо, однако, если вы пишете библиотеку, вам определенно следует освободить всю память в вашей библиотеке, которая является malloc'd в вашей библиотеке. Это связано с тем, что в Windows dll имеет кучи, отличную от exe, поэтому неправильное размещение памяти в dll и освобождение ее в exe приводит к повреждению вашей кучи.
По расширению и ради симметрии это означает, что если у вас есть функция, которая возвращает указатель на выделенную память, то у вас должна быть функция, которая освобождает эту память. Вот почему многие библиотеки имеют функцию инициализации, которая возвращает указатель на некоторые данные (обычно преобразуемые как void *), а затем функцию очистки, которая освобождает ресурсы библиотеки.
Если вы можете использовать malloc и free внутри одной и той же функции, то это хорошо, так как вам будет легко отслеживать вещи.
Не пытайтесь выделить всю свою память в начале функции, а затем освободите ее в конце. Это просто означает, что если вы хотите вернуть часть функции через эту функцию, вам нужно освободить всю память, тогда как если вы используете malloc и освобождаете память по ходу работы, у вас будет меньше указателей на освобождение.
Если у вас часто есть функции, которые выделяют много указателей, подумайте о создании и массиве, который содержит указатели на все ваши указатели в начале функции, а затем используйте функцию, которая освобождает их все. Это избавит вас от неизбежного синдрома «Я вернусь и позже разберусь в утечке памяти», если вы захотите вернуться к середине функции.
Понятие фабрики полезно. Фабрика - это функция, которая выделяет память для структуры, назначает указатель функции на структуру, инициализирует ее переменные и затем возвращает указатель на нее. Если первым из них был деструктор или массив специфических функций, то вы можете иметь универсальную функцию уничтожения, которая может вызывать деструктор любой структуры, а затем освободить память структуры. Вы также можете скрыть некоторые внутренние детали класса, имея различное внутреннее и внешнее определение структуры. COM построен на этих принципах.
Так что я просто смотрю на память в C. Это не так элегантно, как в C ++, но, поскольку вы полагаетесь на людей, чтобы справиться с этим, существуют стратегии, подобные приведенным выше, которые могут сделать вещи простыми. насколько это возможно для них.
Обратите внимание, что всегда есть исключения из каждого правила - это просто вещи, о которых я думаю, когда использую C. Я уверен, что у других людей есть другие идеи.
Phil