从开源软件看动态内存分配

动态内存分配

我们通常在C里面动态分配内存,会写出下面这样的代码:

struct header {
  size_t len;
  unsigned char *data;
};

随后为data malloc一段内存出来,那么还有其他办法吗?

那便是弹性数组!在阐述本节之前,先了解一下这两种写法:

struct header {
  size_t len;
  unsigned char data[1];
};

struct header {
  size_t len;
  unsigned char data[];
};

在实际项目中,会看到这两种写法,下面来重点聊聊它们吧。

方法1:

struct header {
  size_t len;
  unsigned char data[1];
};

这种写法使用了一个长度为1的数组来表示数据部分。这是一种古老的技巧,通常称为"结构体尾部数组"或"伪动态数组"。在早期的C语言标准中,它被广泛用于实现变长结构体。在这种情况下,实际分配给结构体的内存会比sizeof(struct header)大,以容纳更多的数据。通过动态内存分配,可以为data成员分配更多的空间,并根据需要修改len字段的值。这样,结构体实际上可以扩展以容纳变长数据。

方法2:

struct header {
  size_t len;
  unsigned char data[];
};

这种写法使用了一个长度为空的数组。这是C99标准中引入的"弹性数组成员"特性。与前一个例子相比,这种写法更加简洁和直观。它允许在结构体中声明一个可变长度的数组,而无需显式指定长度。使用这种灵活数组成员,可以根据需要为data成员动态分配内存,并根据len字段的值来管理数据的长度。

历史原因是,在早期的C语言标准中,动态分配内存的技术并不像现代的C语言那样成熟。因此,人们使用了一些技巧来实现变长数据的结构体。第一个结构体定义是其中一种技巧的结果。然而,随着C语言的发展和C99标准的引入,灵活数组成员提供了更加方便和安全的方式来处理变长数据。因此,第二个结构体定义更符合现代C语言的实践。

实际项目中的使用这几种方式都会涉及,例如:著名的postgresql数据库,分别使用如下:

1.使用data[1]方式

union pgresult_data
{
    PGresult_data *next;  /* link to next block, or NULL */
    char  space[1];  /* dummy for accessing block as bytes */
};

2.使用data[]方式

0373ca6998da97ae11924ebd78160f63.png

typedef struct TupleDescData
{
 int   natts;   /* number of attributes in the tuple */
 Oid   tdtypeid;  /* composite type ID for tuple type */
 int32  tdtypmod;  /* typmod for tuple type */
 int   tdrefcount;  /* reference count, or -1 if not counting */
 TupleConstr *constr;  /* constraints, or NULL if none */
 /* attrs[N] is the description of Attribute Number N+1 */
 FormData_pg_attribute attrs[FLEXIBLE_ARRAY_MEMBER];
}   TupleDescData;

《C++那些事十日狂练》与《Mysql一周实战》持续更新中...

656b71da87b0022766530ce128934722.png

点击加入!

1f0f55ebe16ed53810f4a637eff520ff.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值