redis数据库中的sds.h中字符串数组的一个说明

在redis源码sds.h中对于字符串结构体的定义如下:
typedef char *sds;
struct sdshdr {
    int len;
    int free;
    char buf[];
};
这里刚开始没有看明白char buf[]是什么个形式,不是说C语言里数组必须要初始化大小吗?那么这里是什么东西?
我们先用一个简单的方法来查看一下结构体sdshdr的大小:
#include <stdio.h>
struct sds
{
 int val;
 int size;
 char name[];
};
int main()
{
 printf("%d\n",sizeof(sds));
 return 0;
}
我们发现输出结果是8字节,也就是说char name[]是不占空间的,这里我们可以把它看成一个占位符。
struct Database
{
  char           Name[];
};

这种结构体声明倒是对的,最新的C标准支持这种写法,但是,初始化它就没这么简单了,前面还没有一个人说对正确的初始化办法呢
并且,这个东西的初始化,只能手工,先用malloc(sizeof(struct Database) + size);
其中size是你希望的Name的长度,然后你只能用strcpy这样的方式初始化了

上面是查找到的资料,实际上这里可以把char buf[]看成一个指针,在struct默认只是占用了指针的空间而已,而不占用实际的存储空间,相反,在生成该结构体实例的时候,才进行空间分配。在redis中空间分配的函数在sds.c中:
sds sdsnewlen(const void *init, size_t initlen) {
    struct sdshdr *sh;
    if (init) {
        sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
    } else {
        sh = zcalloc(sizeof(struct sdshdr)+initlen+1);
    }
    if (sh == NULL) return NULL;
    sh->len = initlen;
    sh->free = 0;
    if (initlen && init)
        memcpy(sh->buf, init, initlen);
    sh->buf[initlen] = '\0';
    return (char*)sh->buf;
}
我们从上述代码可以看出, sh = zmalloc(sizeof(struct sdshdr)+initlen+1);这句话就是根据传进来的参数来申请内存,当然,申请的内存是大于存放字符串的空间的,因为要申请额外的空间用来存放 int len;int free; 两个变量,也就是sizeof(struct sdshdr),其中+1是用来存放表示字符串结束的'\0'。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值