C语言

(改进版)宏实现C语言任意类型的安全数组

2022-10-31  本文已影响0人  黑熊小李

前述

在我的上一篇文章《利用宏实现C语言任意类型的安全数组》中留下的代码,经过我反复品味,发现还有一些不足,例如:

  1. Create_Array 宏的模块化程度不高,有比较重的散装感,也就是耦合度高。
  2. Destroy_Array 宏没有对于情况的仔细分析处理分支,不安全。
  3. 原Array 结构体不应该别称为Array ,它更像是一种通用的安全结构。
  4. 命名上的不规范,不能达到显而易见的效果。

改进

针对以上不足,做出如下改进:

  1. 规范了命名,使得通过名字就能确定所属关系和类型。
  2. 抽象出一个通用的 Box 结构,避免歧义。
  3. 使用单个函数封装了创建 Box 结构的功能,模块化成度更高。
  4. 简化宏的结构,为宏添加必要的处理分支。
  5. 添加了必要的注释,方便阅读。

代码:

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

// 可以通用的 内容+大小 结构
typedef struct {
    size_t size;
    void *private; 
}Box;

// 创建一个Box对象,并为私有成员开辟需要的空间
Box *Box_new(size_t size, size_t typesize) {
    Box *out = calloc(1, sizeof(Box));
    
    if (out != NULL) {
        out->private = calloc(size,typesize);
        
        if (out->private != NULL) { 
            out->size = size; 
            return out;
        }
        else { 
            free(out);
            out=NULL; 
        }
    }

    return out;
}

// 释放分配的空间
void Box_delete(Box *opj){
    if(opj->private != NULL) {
        free(opj->private);
    }
    
    free(opj); 
}

/** if 分配成功 
 *      生成两个指针
 *          一个指向结构
 *          一个具象化的类型指针,指向结构中的私有成员 
 * else 两个堆内存,任意一个分配失败
 *      生成两个空指针
*/
#define Box_get_as_type(name, type)                    \
    type *name##_ptr = NULL;                           \
    if(name != NULL) { name##_ptr = name->private; }   \


#define Box_create(name, type, length)                 \
    Box *name = Box_new(length, sizeof(type));         \

/** if 数组指针不为空
 *  分配的内存,遵循由内部向外部逐步释放原则
 *      优先把 private 的别名指针置空
 *      清理结构体内部动态内存
 *      清理结构体动态内存
*/
#define Box_destory(name)         \
    if(name) {                    \
        Box_delete(name);         \
        name=NULL;                \
    }

void fn(int *opj, size_t size){
    for(int i=0; i < size; i++) {
        opj[i]=i*2;
        if(i < size-1) printf("%d->",opj[i]);
        else printf("%d\n总数:%zu 个\n",opj[i],size);
    }
}

int main(){  
    Box_create(an, int, 10)
    Box_get_as_type(an, int)
    if(an) fn(an_ptr, an->size);
    Box_destory(an)
} 

结果:

Safe_Power

疑问:

在之前印象里,free函数只是释放了这个指针指向的地址,指针值应该不变,但是在这里,结构体中 private 指针释放后,值发生变化,而结构体指针的值却不变的?!都是calloc分配的,怎么会有诡异的现象?虽然不耽误啥,但就是想不通。


注意

文章为本人在简书平台原创,盗用必究!

上一篇下一篇

猜你喜欢

热点阅读