На вашем первом шаге
int *i;
// do stuff
i = NULL;
Если бы я указал на что-то, что выделило память, разве эта память не будет потеряна навсегда (утечка памяти)?
Например:
int *i;
i = (int*) malloc(sizeof(int);
i = NULL;
оставил бы кусок памяти размером с int, оставленный в эфире.
То же самое верно для ваших примеров some_func (), но я думаю, что вы тестируете правильно, пытаясь освободить то, что осталось от some_func (). Особенно, если вы не знаете, как работает some_func ().
Если some_func () из библиотеки, может существовать функция free_some_func (i), которая сделает эту работу за вас.