c - 指针 union 的动态分配 - C

标签 c memory-management unions

我正在用 C 编写一个用于低级图像处理的基本库。我知道存在其他(非常好的)库;这对我来说是一次学习经历,而不是达到目的的手段。

我已经定义了以下(针对这个问题进行了简化)结构:

union img_rawdata{
    uint8_t*  u8;
    uint16_t* u16;
    float*    flt;
};

enum img_type{
    IMG_U8,
    IMG_U16,
    IMG_FLT
};

struct image{
    union img_rawdata  rawdata;
    enum img_type      type;
    unsigned int       num_values;
};

我的问题是:在 union 内动态分配正确指针的最佳方式是什么?

现在,我看到的唯一方法是使用 switch 语句,例如:

void alloc_img(struct image* img, enum img_type type, unsigned int num_vals){
    switch (type){
        case IMG_U8:
            img->rawdata.u8 = (uint8_t*)malloc(num_vals*sizeof(uint8_t));
        break;            
        case IMG_U16:
            img->rawdata.u16 = (uint16_t*)malloc(num_vals*sizeof(uint16_t));
        break;
        case IMG_FLT:
            img->rawdata.flt = (float*)malloc(num_vals*sizeof(float));
        break;
    }
}

这看起来还不错;然而,在我的实现中,实际的内存分配大约是 50 行(因为原始数据不是一维的,错误检查等)。

是否有任何可以减少代码冗余的预处理器魔术,或者这是编写此代码的最佳方式吗?

或者,是否有完全不同的方法来解决可以完全避免此问题的问题?

最佳答案

[假设包括void *在内的所有类型的指针都具有相同的大小]

修改你喜欢的东西

union img_rawdata {
  void * untyped;
  uint8_t * u8;
  uint16_t * u16;
  float * flt;
};

enum img_type {
  IMG_UNDEF = -1
  IMG_U8 = 0,
  IMG_U16,
  IMG_FLT,
  IMG_MAX
};

并添加

const size_t img_type_size[IMG_MAX] = {
  sizeof(*((union img_rawdata *) NULL)->u8),
  sizeof(*((union img_rawdata *) NULL)->u16),
  sizeof(*((union img_rawdata *) NULL)->flt)
};

然后将开关替换为:

assert(IMG_UNDEF < type && IMG_MAX > type);
img->rawdata.untyped = malloc(num_vals * img_type_size[type]);

关于c - 指针 union 的动态分配 - C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23169171/

相关文章:

python - 使用 Ctypes 从 Python 传递 C 结构指针

c - Linux,从条码扫描仪读取

c++ - 在 C++ 中为结构( union )创建构造函数

C++ union 数组和变量?

c - 如何检查 C 中的 union 是否不是 "initialized"?

c - C中指针的问题

c - 解析从文件中读入的字符串

objective-c - 在 viewDidUnload 和 dealloc 中都释放?

c - 堆栈转储访问 malloc 字符数组

linux - 在 Linux 上,为什么我们的页面大小如此之大 (60GB)。每个进程都得到一份副本吗?