zoukankan      html  css  js  c++  java
  • __attribute__系列之cleanup

    cleanup属性:当变量离开它的作用域时,设置的cleanup_function函数将被调用。

    cleanup (cleanup_function)

    The cleanup attribute runs a function when the variable goes out of scope. This attribute can only be applied to auto function scope variablesit may not be applied to parameters or variables with static storage durationThe function must take one parameter, a pointer to a type compatible with the variable. The return value of the function (if any) is ignored.

    If -fexceptions is enabled, then cleanup_function will be run during the stack unwinding that happens during the processing of the exception. Note that the cleanupattribute does not allow the exception to be caught, only to perform an action. It is undefined what happens if cleanup_function does not return normally.

    #include <stdio.h>
    #include <stdlib.h>
    
    #define local_type  __attribute__ ((cleanup(my_free)))
    
    static void my_free(void* pmem)//the type of paramter must be a void pointer
    {
          printf("pmem=%p...
    ", pmem);
          printf("&pmem=%p...
    ", &pmem);
          void** ppmem = (void**) pmem;
          printf("*ppmem=%p...
    ", *ppmem);
          free(*ppmem);
    }
    
    #if 0
    //warning: passing argument 1 of ‘my_free’ from incompatible pointer type
    static void my_free(void** ppmem)
    {
          printf("ppmem=%p...
    ", ppmem);
          printf("*ppmem=%p...
    ", *ppmem);
    }
    #endif
    
    int foo(void)
    {
        local_type int* p = (int*) malloc(sizeof(int));
        printf("do something, p=%p
    ", p);
    
        return 0;
    }
    
    int main(int argc, char** argv)
    {
    
        foo();
        // when return, the memory block pointed by p is freed automatically
        printf("11111111
    ");
    
        return 0;
    }

    利用cleanup属性来实现智能指针:

     1 #include <stdlib.h>
     2 #include <stdio.h>
     3 
     4 struct shared_ptr_s
     5 {
     6     //    struct impl_t* inst;
     7     int *use_cnt;
     8 };
     9 
    10 typedef struct shared_ptr_s shared_ptr_t;           // unadorned type
    11 #define shared_ptr struct shared_ptr_s __attribute__((cleanup(free_shared)))
    12 
    13 #define SHARED_PTR_GET_ADD_REF(sp_in, sp_name) ++(*sp_in.use_cnt); 
    14                         printf("add use_cnt = %d, sp_in=%p
    ", *sp_in.use_cnt, sp_in); 
    15                         shared_ptr sp_name = sp_in; 
    16                         printf("&sp_name=%p, sp_name:%p
    ", &sp_name, sp_name);
    17 
    18 void free_shared(struct shared_ptr_s* ptr)
    19 {
    20     printf("ptr:%p, usr_cnt:%p
    ", ptr, ptr->use_cnt);
    21     if(!ptr) return;
    22     printf("del use_cnt = %d
    ", *ptr->use_cnt - 1); 
    23     if(0 == --(*ptr->use_cnt)) {
    24         //dtor(ptr->inst);
    25         printf("freeing %p
    ", (void *)ptr->use_cnt);
    26         free(ptr->use_cnt);
    27     }
    28     //ptr->inst = 0;
    29     ptr->use_cnt = 0;
    30 }
    31 
    32 void func(shared_ptr_t sp)
    33 {
    34     SHARED_PTR_GET_ADD_REF(sp, sp_loc);
    35     printf("111111111
    ");
    36     return;
    37 }
    38 
    39 int main(void)
    40 {
    41     shared_ptr_t sp = {         // original type does not use __attribute__(cleanup)
    42         //.inst = ctor(), 
    43         .use_cnt = malloc(sizeof(int)) 
    44     };
    45     printf("use_cnt content addr:%p, &use_cnt=%p, &sp=%p,sp=%p
    ", sp.use_cnt, &sp.use_cnt, &sp,sp);
    46     SHARED_PTR_GET_ADD_REF(sp, sp_loc);
    47 
    48     printf("222222222222
    ");
    49     func(sp_loc);
    50     printf("333333333
    ");
    51 
    52     return 0;
    53 }

    运行结果:

    use_cnt content addr:0x9ee7008, &use_cnt=0xbfa11dac, &sp=0xbfa11dac,sp=0x9ee7008
    add use_cnt = 1, sp_in=0x9ee7008
    &sp_name=0xbfa11da8, sp_name:0x9ee7008
    222222222222
    add use_cnt = 2, sp_in=0x9ee7008
    &sp_name=0xbfa11d74, sp_name:0x9ee7008
    111111111
    ptr:0xbfa11d74, usr_cnt:0x9ee7008
    del use_cnt = 1
    333333333
    ptr:0xbfa11da8, usr_cnt:0x9ee7008
    del use_cnt = 0
    freeing 0x9ee7008

  • 相关阅读:
    plsql各版本官网下载地址
    docker容器启动rabbitmq并开启web控制台
    SM3杂凑算法实现
    快速设置IP、DNS等信息的bat脚本
    Windows下nginx的启动,重启,关闭等功能bat脚本
    记一次docker容器中运行springboot程序日志打印的中文变成问号
    calico 指定pod 网段
    helm 的安装使用
    K8s 节点断开连接后,本在运行的 Pod 会如何?
    nginx docker 安装ping 命令
  • 原文地址:https://www.cnblogs.com/black-mamba/p/6786603.html
Copyright © 2011-2022 走看看