LinuxForum.Fans
Тема

Си (без плюсов), манипуляции с памятью

Автор: enRai 15 сообщений 4111 просмотров
#21501

Здрасте! Вразумите меня глупого. Пишу прогу на си. В ней куча разнокалиберных массивов.
Запись типа:

text

int i[255];

Не особо приемлю чисто из эстетических соображений. Делаю выделение памяти:

text

int *i;
int n;
//...
i = (int)malloc(sizeof(int)*n);

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

В си++ не вопрос... Класс - конструктор - деструктор. Но в си то классов нет...

#21502

функция free()?

#21506

Ну да, free :) Вопрос только не в этом... Вот к примеру 10 массивов. И 10 ситуаций, в которых прога досрочно завершается. Итого получается 100 раз free надо написать... Как-то не рационально...

#21513

enRai,
При внештатной ситуации придется делать. А как вы эту внештатную ситуацию ловите?

#21517

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

text

if(!var1) {
free(var2);
free(var3);
...
free(varn);
return 1;
}

Однако надо было на с++ делать... Лишние проблемы себе только делаю :)

#21525

enRai,
Если Вы сами отловили такую ситуацию и вызвали exit() (не из функции!!! Из программы!!!), например, то память освободится и так. В противном случае все программеры имели бы большую проблему при внештатных ситуациях. А вот если после такой фигни ваша прога продолжит работу как не бывало, то тут вы получите проблем, и немало.

#21542

Во! Я ведь надеялся :) А вот про exit не знал, что память чистит. Спасибо всем огромное :)

#21544

enRai,
Там есть два значения передаваемого в нее параметра: EXIT_SUCCESS и EXIT_FAILURE. Честно говоря, так сразу не помню, к каким последствиям приводит передача того или иного. Погуглите, я думаю, не проблема найти

#21551

Ага, благодарю. Про параметр я еще со времен Turbo C помню. Это значение, возвращаемое самой программой. Если программа успешно завершила свои действия - то EXIT_SUCCESS (или 0), если неудачно - то EXIT_FAILURE (или 1). Потом в командной строке (в досе дело было) можно было получить этот параметр. Если, конечно, я ничего не напутал.. Давно это было :)

#21650
enRai написал:
Не особо приемлю чисто из эстетических соображений...

Если размеры массивов известны на этапе компиляции, то в том числе по эстетическим соображениям выделять память следует статически. А вообще, в Си достаточно широко распространен такой подход:

text

int myfunction (void* arg)
{
    void* ptr = NULL;
    
    ....

if (somefunction() == -1) goto cleanup;

...

return 0;

cleanup: /* * Чистим память, закрываем соединения... */ if (ptr != NULL) free(ptr); return -1; }

Иными словами, код за меткой cleanup играет роль Плюсового catch.

#21947

Да, если известны, то полностью согласен. А про goto я тоже думал изначально. Но как-то коряво код выглядит сразу :) А за совет благодарю :)

#23915

Вообще то стандарт C гарантирует что free(NULL) ничего не сделает, так что не вижу смысла в проверках

text
if (ptr!=NULL) free();

и если в функции возникла внешатная ситуация, нужно просто вызвать free() для всех массивов.

#23925
enRai написал:

В си++ не вопрос... Класс - конструктор - деструктор. Но в си то классов нет...

6.29 Declaring Attributes of Functions
constructor (priority)
destructor (priority)
The constructor attribute causes the function to be called automatically before execution enters main (). Similarly, the destructor attribute causes the function to be called automatically after main () has completed or exit () has been called.

#23996
FIL написал:
Вообще то стандарт C гарантирует что free(NULL) ничего не сделает, так что не вижу смысла в проверках
text
if (ptr!=NULL) free();

Не делается лишний вызов функции, т.е. уменьшаются накладные расходы.

Пётр.

Войдите или зарегистрируйтесь, чтобы ответить.