How to free memory from an internal malloc to a function that returns a pointer?

5

How to release an inner% of% to a function that returns a pointer? In a simple way to try to exemplify my doubt, consider the following malloc function:

int *f(int tam)
{
    int *ptr = malloc(tam * sizeof *ptr);

    return ptr;
}

It uses dynamic memory allocation within the function and returns the allocated pointer. I'm using, in a function (as f ) of the form:

int main(void)
{
    int tamanho = 5;

    int *ponteiro;

    ponteiro = f(tamanho);

    if(ponteiro != NULL)
    {
        free(ponteiro);
    }
    else
        puts("Memória insuficiente.");      

    return 0;
}

Where main receives the return of the ponteiro function. Would it be responsible for checking for available memory and giving f() on free() of function as described above in malloc() ?

If it is, in compound functions in call, would it also be done this way? The example below shows two functions: one calling the other,

#include <stdio.h>
#include <stdlib.h> 

int *f(int tam)
{
    int *ptr = malloc(tam * sizeof *ptr);

    return ptr;
}

int *g(int *ptr)
{
    return ptr;
}

int main(void)
{
    int tamanho = 5;

    int *ponteiro;

    ponteiro = g(f(tamanho));

    if(ponteiro != NULL)
    {
        free(ponteiro);
    }
    else
        puts("Memória insuficiente.");      

     return 0;
}

Would it be the pointer that receives the "final" return that is responsible for the dynamic allocation of main ? And so indefinitely for such composite functions?

    
asked by anonymous 22.02.2015 / 21:08

2 answers

4

The basic rule is do not do this . But if you do the path is this one you presented. There is not much to invent. That is, if you will not follow an organization rule that everyone establishes as the clearest, then create your rule and take the risk.

The ideal is to always leave the function responsible for allocating memory responsible for releasing it. You rarely have any advantage in doing differently. In general, the philosophy of C functions that need an allocated memory that can exist beyond its duration is always to receive a pointer to the memory previously allocated by another code. It is rare, and usually considered wrong, to allocate memory and return it for external use to the creative function.

The reason for this "rule" is precisely not to make it even harder to follow the lifetime of an object. It is very easy not only to make mistakes but to create potentially dangerous situations. It may seem simple in an example contained like this, but in a real code it is very complicated to know if you should release the memory and if it has not yet been released.

Whoever allocates memory should be responsible for all necessary treatment. If you do not do this, be prepared to handle complicated management unnecessarily.

Following some rules, managing dynamic memory in C is not that difficult. Of course, you can still forget what to do, you can make mistakes, get confused, but following a good organization you do not get lost easily as some people imagine.

The example is pretty bad to demonstrate anything really useful but just to show the right way to do something similar:

#include <stdio.h>
#include <stdlib.h> 

int *f(int *ptr) {
    //faz alguma coisa com ptr aqui
    //do jeito que estava aqui, uma chamada do jeito errado criaria confusão
    //ainda não está ideal mas o exemplo todo não está
    return ptr;
}

void g(int *ptr) {
    //faz alguma coisa com ptr aqui
    return;
}

int main(void) {
    int tamanho = 5;
    //o importante é que o malloc agora está próximo do free, fica mais fácil acompanhar
    int *ponteiro = malloc(tamanho * sizeof *ponteiro); 

    g(f(ponteiro));

    if(ponteiro != NULL) { //só isto não garante nada em um exemplo mais completo
        free(ponteiro); //não é difícil associar este free ao malloc logo acima
    } else {
        puts("Memória insuficiente.");      
    }
     return 0;
}

Do not get a solution and look for a problem to apply it. Find the best solution for a problem you have.

I only know three reasons to treat the release elsewhere:

  • artificially want to decrease a code in one place (does not mean it's a good thing);
  • have a memory management function that helps the job (few people know how to do this right);
  • is using something created by third parties and therefore you have no control to fix it.
  • In general APIs in C require the consumer to be responsible for allocating memory, it is rare to deliver a memory allocated by the used API.

    Even though it seems right in a simple example it can be a bad idea in more complex examples.

    C is a language where management must be done manually and needs great care. If this care is taken and it is not so difficult. If you prefer more automatic management choose C ++ or a language with garbage collector .

        
    22.02.2015 / 21:29
    1

    However, if the allocation you are going to do requires a bit more performance and the function that is allocating the memory itself will be the same as the deallocation, if that size is not __libc_use_alloca(size) (in the case of GCC), use the alloca(); function would best fit the situation since it gains in performance by not using the heap and it itself already deallocates the allocated memory without the need to use free(); by avoiding memory leaking . If this is not the case, then performance is not a priority at this time, consider using calloc(); since it allocates and initializes the space allocated with zeros.

    = - D

        
    06.11.2015 / 03:19