Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto release of stack variables in C

Unfortunately, in C there aren't any smart pointers.. but is it possible to build a macro that wrap variable declaration and invoke function call with that variable as an input variable upon leaving the scope where the variable was declared ?

Sorry for the long phrase, but I'm working on xnu kernel where you have many elements that have built-in reference counters, and one must not forget to unref this element when done using it to avoid memory leaks.

For example, if I have the following type of proc_t:

struct proc; typedef struct proc * proc_t; 

I want to declare a stack variable based on this type within a scope, for example :

{     proc_t_release_upon_exit proc_t proc_iter = proc_find(mypid);     //the rest of the code in this scope  } 

After preprocessor analyze the macro and before compilation, the following code I expect to be generated is :

{      proc_t myproc = proc_find(mypid)     //the rest of the code in scope     proc_rele(myproc); } 

Is there any way to define such macro as in C ?

like image 690
Irad K Avatar asked Jun 29 '17 07:06

Irad K


1 Answers

You could use the cleanup variable attribute in GCC. Please take a look at this: http://echorand.me/site/notes/articles/c_cleanup/cleanup_attribute_c.html

Sample code:

#include <stdio.h> #include <stdlib.h>  void free_memory(void **ptr) {     printf("Free memory: %p\n", *ptr);     free(*ptr); }  int main(void) {     // Define variable and allocate 1 byte, the memory will be free at     // the end of the scope by the free_memory function. The free_memory      // function will get the pointer to the variable *ptr (double pointer     // **ptr).     void *ptr  __attribute__ ((__cleanup__(free_memory))) = malloc(1);     return 0; } 

If you save the source code in a file named main.c, you could compile it with this command:

gcc main.c -o main 

and verify if there are any memory leaks by:

valgrind ./main 

Example output from valgrind:

==1026== Memcheck, a memory error detector ==1026== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==1026== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==1026== Command: ./main ==1026==  Free memory: 0x51ff040 ==1026==  ==1026== HEAP SUMMARY: ==1026==     in use at exit: 0 bytes in 0 blocks ==1026==   total heap usage: 1 allocs, 1 frees, 1 bytes allocated ==1026==  ==1026== All heap blocks were freed -- no leaks are possible ==1026==  ==1026== For counts of detected and suppressed errors, rerun with: -v ==1026== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 
like image 95
Maciej Malinowski Avatar answered Sep 22 '22 18:09

Maciej Malinowski