php扩展 c 结构体,【原创】关于C语言的变长结构体(内嵌柔性数组):C Struct Hack...

问题背景:

在PHP内核的字符串实现源码中我们发现了这么一个结构体如下:

struct _zend_string {

zend_refcounted_h gc;

zend_ulong h; /* hash value */

size_t len;

char val[1];

};

也就是说PHP的字符串底层实现并没有使用char *,而是使用了这么一个结构体,并且字符串的内存存储在val柔性数组当中,那么其中的 char val[1] 是什么意思呢?

柔性数组:

C99关于变长结构体(学名:C Struct Hack)是这样描述的:

As a special case, the last element of a structure with more than one named member mayhave an incomplete array type; this is called a flexible array member.

问题解决:

根据C99描述可知 char val[1] 是柔性数组的用法,事实上字符串分配内存空间时是这样的: malloc(sizeof(zend_string) + 字符串长度),也就是会多分配出一些内存,而多出来的这部分内存的的起始位置正好是val,如此我们就能直接存储字符串内容啦;另外注意val[1]并不是表示只能存储一个字节,而使用val[1]而不使用val[0]的原因则是多出来这么一个字节用于存储字符串末尾的结束符'\0'.

问题补充:

1、柔性数组只能是变长结构体的最后一个成员;

2、变长结构体必须至少包含2个成员;

源码展示:

#include

#include

#include

struct mystring

{

int len;

char val[1];

};

typedef struct mystring Mystring;

Mystring *createDynamicString(char *str, size_t len);

int main()

{

Mystring *p;

p = createDynamicString("baidu", strlen("baidu"));

printf("%d-%s\n", p->len, p->val);

free(p);

p = createDynamicString("google", strlen("google"));

printf("%d-%s\n", p->len, p->val);

free(p);

return 0;

}

Mystring *createDynamicString(char *str, size_t len)

{

Mystring *ptr;

ptr = (Mystring *)malloc(sizeof(Mystring) + len + 1);

if(ptr == NULL) return NULL;

ptr->len = len;

printf("%d\n", sizeof(Mystring) + len + 1);

memcpy(ptr->val, str, len);

return ptr;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值