LINUX.ORG.RU

Кошерно ли выделять память внутри функции?


0

0

Нормально ли выделять память внутри функции, а затем выдавать указатель на нее в качестве возвращаемого значения (ну или NULL )?

Меня терзают смутные сомнения, что лучше выделять память на том уровне вложенности, где ее и освобождаешь, а возвращаемое значение оставить для сигнализации об ошибках или void. В данном случае функция кроме математических вычислений ничем не занимается, пока ошибок не придумал.

anonymous
Ответ на: комментарий от dilmah

кошерно не то что ты ешь, а как ты это ешь..

dilmah ★★★★★
()
Ответ на: комментарий от wfrr

А можно узнать почему - если конечно это не стеб ? Я всегда думал что это вполне нормально. Еще я думал что это дело компилятора заботиться о выделении памяти - например если память выделяется и освобождается на одном уровне - использовать стэк и тд.

P.S. Другой анонимус

anonymous
()

Учитывая, что malloc так и делает, наверное кошерно.

ilya_ost
()

Это нормально. Мало того, иногда без этого не обойтись. Главное -- не забывать освобождать выделенную память.

Demon37 ★★★★
()
Ответ на: комментарий от anonymous

>А можно узнать почему - если конечно это не стеб ? Я всегда думал что это вполне нормально.

Ибо вы сами через месяц используя эту функцию забудете, что нужно освобождать память. Собственно других причин наверняка и нет.

З.Ы. Другой другой анонимус

anonymous
()
Ответ на: комментарий от dilmah

> нормально. Просто должна быть четко определенная дисциплина..

Просто должна быть ОПРЕДЕЛЕНА дисциплина. Такие функции хуже тем, что требуют от вас больше согласований, чем обычно. Это вопрос дисциплины. С точки зрения уменьшения требований к дисциплине (переходя от машинных кодов на ЯВО), от таких функций лучше отказываться, когда есть возможность.

irc_007_1
()
Ответ на: комментарий от anonymous

Верно, другой анонимус объяснил за меня. Фактически это "нехороший" стиль. Кроме того, если функция будет вызываться из другой библиотеки, могут быть различные интересные эффекты.

wfrr ★★☆
()
Ответ на: комментарий от anonymous

>Ибо вы сами через месяц используя эту функцию забудете, что нужно освобождать память

Можно комментарий к прототипу функции написать и все.

Demon37 ★★★★
()

если вынести выделение памяти из функции отладка будет куда как проще. вообще разносить зеркальные операции по разным логическим уровням стоит только если для этого есть очень веские причины

jtootf ★★★★★
()
Ответ на: комментарий от wfrr

> /**
> * Oh, shit! Ne trogat nicheo inache nixera ni rabotaet!
> */

Автора таких комментов надо подвергать разговорам...

irc_007_1
()
Ответ на: комментарий от Demon37

Себе вы уже посочувствовали с вашим-то подходом к решению проблем?

wfrr ★★☆
()

имхо, лучше вообще использовать отдельную функцию для выделения стрктуры, отдельные функции для работы с ней и еще одну функцию для ее очищения/удаления. это избавит от необходмости дублировать код где эту структуру только не используешь.

получится довольно удобно: выделил, поработал, удалил.

но! valgrind еще никто не отменял. в принципе, его всегда хорошо использовать!!!

anonymous
()
Ответ на: комментарий от anonymous

к тому же дополнительная прослойка между уровнем, где эта структура используется, и уровнем malloc-а (читай выделения памяти под структуру) - это всегда хорошо. больше простора для расширяемости

anonymous
()

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

anonymous
()
Ответ на: комментарий от anonymous

аргументация сторонников моих сомнений мне пришлась более по душе

anonymous
()
Ответ на: комментарий от anonymous

s/необходмости/необходимости/ s/только не используешь/только ни используешь/

anonymous
()
Ответ на: комментарий от anonymous

> имхо, лучше вообще использовать отдельную функцию для выделения
> стрктуры, отдельные функции для работы с ней и еще одну функцию
> для ее очищения/удаления

Именно. Сам всегда делаю конструкторы/деструкторы. В этом случае точно ничего не забудешь.

Deleted
()


более чем кошерно, но с одним но: если это C++, то это *или* malloc/free *или* new/delete но никак не смесь. точнее, даже так - это *только* new/delete.

// wbr

klalafuda ★☆☆
()

Зависит от того, что функция делает, лучше избегать подобных побочных эффектов, если логически от функции требуются только вычисления и память нужна под их результаты.

Передавать надо уже выделенную память, а если необходимый объём заранее не известен, то структуру (объект класса, если поддерживается ООП) со _своими_ методами добавления новых элементов в структуру и вызывать надо их, а не просто память выделять.

Помимо опасности забыть освободить память, могут быть трудности, если функция попадёт в отдельную библиотеку, а в вызывающей программе будет свой аллокатор памяти и т.п.

anonymous_incognito ★★★★★
()
Ответ на: комментарий от Bohtvaroh

кстати, да. при том там грамотная система сигнатур: g_blah_blah_new(param, pam, pam) всегда что-то выделит, а g_blah_blah_destroy() уничтожит. удобно и логично.

Pi ★★★★★
()
Ответ на: комментарий от dilmah

> /* return value is owned by caller */

Или ещё модно "The returned value should be freed when no longer needed". ;-)

Bohtvaroh ★★★★
()
Ответ на: комментарий от Pi

> кстати, да. при том там грамотная система сигнатур

Ну и плюс к этому упрощённое управление памятью, вроде того, что виджет, получив сигнал "destroy" заодно подчистит всех своих детишек, ну и всяческие g_object_ref/unref для полноты картины. :)

Bohtvaroh ★★★★
()

У нас в компании принят определенный стиль. Так вот функция, за исключением очевидных случаев, должная возвращать int. При этом -1 означает ошибку, а 0 успешное завершение. Если функция вернулась с ошибкой, я не должен ничего освобождать, иначе должен однозначно. Как правило это выглядит так:

int something_new(something_ctx ** ctx);
int something_set_lalala(something_ctx *ctx, lalala_t * la);
void something_free(something_ctx *ctx);

Ну и все, использование простое.

something_ctx *ctx;
if (something_new(&ctx)) {
return -1;
}
if (something_set_lalala(ctx, LALA)) {
something_free(ctx);
return -1;
}

....

rymis ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.