Is it correct to clean an internal malloc to a function with it?

Asked

Viewed 207 times

1

Well given the following code is easy to do memory management:

Code Example (in C):

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

int *criarValor(void){

   int *valor  = malloc(sizeof *valor);

   *valor = 10;

   return valor;
}

int main(void)
{
   int *valorPtr;

   valorPtr = criarValor();

   /* Usa um ponteiro para acessar os valores */
   printf("O valor na heap é: %d\n", *valorPtr); 

   /* Libera memória alocada */
   free(valorPtr);

   return 0;
}

But if dereferencing is done through the function itself? Is it possible (and/or necessary) to give free in the function? Follow the example of how such a case would be:

Doubt case (in C):

int *criarValor(void){

   int *valor  = malloc(sizeof *valor);

   *valor = 10;

   return valor;
}

int main(void)
{
   /* Usa a própria função dereferenciada para acessar os valores */
   printf("O valor na heap é: %d\n", *criarValor()); 

   /* É correto dar esse free? A memória alocada 
      é corretamente liberada? */
   free(criarValor());

   return 0;
}

The doubt continues in C++:

Doubt code (in C++):

#include <iostream>

int *criarValor(void){

   int *valor  = new int(10);

   return valor;
}

int main()
{ 
   // Usa a própria função dereferenciada para acessar os valores
   std::cout << "O valor no heap é : " << *criarValor() << std::endl;

   // É correto dar esse deletada? A memória alocada 
   // é corretamente liberada?
   delete criarValor();
}

The allocated memory is being released correctly?

  • In the last two examples, you allocate two values, but only release one.

  • How do I allocate two values? I just created a memory region that fits an integer.

  • Each function call makes a distinct allocation, no?

  • The doubt is the second call, precisely in the free (delete).

  • 2

    Look, I’m weak in C and absolutely ignorant in C++, but in my mind your free only releases the memory that was just allocated to the call you have in there. The call inside the printf made another allocation, and you can’t release that memory because you didn’t save the pointer returned on the first call.

  • That is the doubt.

  • I think the point here is that each malloc call will allocate a new memory area, so in your code the line "free(createValor();" will free the memory allocated by the call to createValue that it is within the call to free and not the memory previously allocated by "printf("The value in the heap is: %d n", *createValue());",

Show 2 more comments

1 answer

3


But if dereferencing is done through the function itself?

When you do free(foo()), you are not doing the free "through foo". You are simply giving free on the return value of foo(). It is as if you have done

 int *tmp = foo();
 free(tmp);

Similarly, in your printif you are not "using the proper dereferenced function", you are changing the pointer returned by the function.

An easy way to see this is to put a printf inside the criarValor. You’ll see that you’re running the function twice.

In C the best thing you can do is write the program as in your very first example. If you don’t put the pointer statement separately doesn’t even get that bad:

int main(void)
{
   int *valorPtr = criarValor();

   /* Usa um ponteiro para acessar os valores */
   printf("O valor na heap é: %d\n", *valorPtr); 

   /* Libera memória alocada */
   free(valorPtr);

   return 0;
}

If your problem is that the middle of the code has more than one exit point, use goto:

int main(void)
{
   int *valorPtr = criarValor();

   if(valor == 17){
      /* Erro, abortar */
      goto cleanup;
   }else{
      printf("O valor na heap é: %d\n", *valorPtr); 
   }

  cleanup:
   free(valorPtr);

   return 0;
}

In C++ you have one more option. Objects run their destructors as soon as they leave the scope and you can put delete inside these destructors.

For example, you can put your pointer inside a smart pointer. In more modern versions of C++ they are part of the standard library.

#include <memory>

int main()
{
   std::unique_ptr<int> valorPtr(criarValor());

   std::cout << "O valor no heap é : " << *valorPtr << std::endl;

   // Assim que essa função retorna e valorPtr sai do escopo,
   // o destrutor do unique_ptr roda e dá delete no conteúdo.
   return 0;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.