c# 在C中使用带有cleanup属性的嵌套函数,(GCC编译器)

7fyelxc5  于 2023-06-20  发布在  C#
关注(0)|答案(1)|浏览(174)

我现在正试图在我的空闲时间打破C。我想使用cleanup属性来释放一个基于第一层长度的矩阵。

#include<stdio.h>
#include<stdlib.h>
void free2d(void * param,int inp){
    void ** unpacked=*((void ***)param);
    for(int i=0;i<inp;i++) free(unpacked[i]);
    free(unpacked);
}
#define BAKE_FREE2D(len) void wrapFree2dl##len (void * ptr){free2d(ptr,len);}
#define AUTOFREE(len) __attribute__((cleanup (wrapFree2dl##len)))
void main(){
    BAKE_FREE2D(5);
    int ** AUTOFREE(5) a=malloc(5*sizeof(void*));
    for(int i=0;i<5;i++) a[i]=malloc(10*sizeof(int));
}

这段代码运行良好。
然而,我想做的是设备一个宏,不需要BAKE_FREE2D宏。我尝试的一件事是使用像({void fct(void*ptr){free2d(ptr,5);};&fct})这样的“lambda表达式”。但是,要使用cleanup属性,必须创建一个标识符。我使用的是GCC编译器,并不打算将这样的代码移植到其他编译器上,所以使用编译器特定的语法是一个选项,而且可能是必需的。

bpzcxfmw

bpzcxfmw1#

BAKE_FREE2D(5);
//          ^
int ** AUTOFREE(5) a=malloc(5*sizeof(void*));
//              ^           ^
for(int i=0;i<5;i++)
//            ^

5无处不在。2d应该是一个具有构造函数和析构函数的对象。虽然这不能直接回答您的问题,但请考虑以下设计。通过将行计数信息封装到对象本身,它与指向对象的指针一起传递给自由函数。

struct matrix {
   int **d;
   size_t x, y;
};
struct matrix *matrix_new(size_t x, size_t y) {
   // blabla
}
void matrix_free(struct matrix *p) {
   // blabla
}
#define MATRIX_AUTOFREE()  __attribute__((__cleanup__(matrix_free)))
int main() {
   MATRIX_AUTOFREE() struct matrix *m = matrix_new(10, 5);
}

您可能也有兴趣探索其他“autocleanup in C”项目,例如:https://github.com/aperezdc/autocleanuphttps://docs.gtk.org/glib/auto-cleanup.html

相关问题