Вы должны сделать различие между потерянным и все еще достижимым динамическим выделением (так же, как это делает Valgrind): если больше нет указателя на динамическую память, то эта память равна потерян , и это следует рассматривать как программную ошибку, независимо от того, находится ли она в цикле и растет, или просто отключается.
С другой стороны, если вы выделяете пару глобальных ресурсови не убирайте их, тогда они просто все еще достижимы : Вы могли бы освободить его, если хотите, но вы просто не беспокойтесь.Это другая проблема, и хотя она может быть не очень элегантной (и неясной отладкой), это также не конец света.
Вот пример:
void * p, * q = malloc(100);
for (int i = 0; i != 10; ++i)
{
p = malloc(15);
}
В этой ситуациипамять в q
все еще доступна, и вы можете освободить ее с помощью free(q);
в конце.С другой стороны, девять из десяти выделений в цикле потеряны , и вы никогда не сможете их восстановить.
Вот как вы можете создать что-то вроде цикла для обеспечения безопасности: makeсоглашение о том, что указатель всегда равен NULL или действителен.
void * p = 0;
void free_it(void ** q) { free(*q); *q = NULL; }
void make_something(void *q)
{
free_it(q);
if (some_condition()) { q = malloc(100); }
}
int main()
{
p = malloc(25);
// ...
make_something(p);
// ...
free_it(p);
// ...
}
По сути, независимо от того, используете ли вы в данный момент динамическую память или нет, p
всегда будет точно отражать это состояние и в любое время, когда вам захочетсячтобы выделить что-то новое, вы можете безопасно освободить предыдущее значение указателя, потому что оно либо допустимо и должно быть освобождено, либо равно нулю.