sizeof在C中的用法
我正在阅读redis的源代码。 代码如下:sizeof在C中的用法,c,redis,C,Redis,我正在阅读redis的源代码。 代码如下: typedef char *sds; struct sdshdr { unsigned int len; unsigned int free; char buf[]; }; static inline size_t sdslen(const sds s) { struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr))); return sh->len; }
typedef char *sds;
struct sdshdr {
unsigned int len;
unsigned int free;
char buf[];
};
static inline size_t sdslen(const sds s) {
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
return sh->len;
}
static inline size_t sdsavail(const sds s) {
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
return sh->free;
}
关于此代码,我有一些问题:
sizeof(struct sdshdr)
8的输出?为什么不包括char buf[]
size\u t sdslen
和sdsavail
。为什么structsdshdr*sh=(void*)(s-(sizeof(structsdshdr))代码>
sh
设置为指向通过取s
的值、一个char*
并减去sds报头的大小而计算的内存。换句话说,从指向字符串的第一个字符(灵活数组成员)的指针开始,我们计算指向头本身的指针,这样就可以得到长度size\u t
中,传递的变量是属于*sds
的s
,它是字符的类型定义
这将导致在内存中实现此代码
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-sdshdr结构。这是一个强制转换,没有意义。无法安全地将字符指针转换为结构指针,这违反了严格的别名。此外,在typedefs后面隐藏指针是非常糟糕的做法。@Lundin这就是(void*)
所要解决的问题,对吗?传入的指针是char*s
,您可以从中减去。然后将结果强制转换为void*
,这会将fine转换为struct shdr*
(但更短更一般)。@Lundin我很确定这里没有字符串别名问题,因为指针的值已更改,并且在减法后指向实际的结构对象。例如,如果字符串本身将被重新解释为一个结构,但它不是。Struct被解释为使用兼容类型的Struct。(char*也可以指向任何对象。)你能给我一个关于struct-sdshdr*sh=(void*)(s-(sizeof(struct-sdshdr)))的详细解释吗代码>?我不明白。s
是内存中的一个指针,它似乎指向一个struct-sdshdr
,然后s-(sizeof(…)
在struct之前计算这个的地址。这可以写成((struct-sdshdr*)s)-1
@BlackMamba:此行的作用是,为sh=malloc/calloc创建一个内存空间,然后检查该字符是否为初始len,并在末尾添加1。然后设置其完整长度,并检查该行的内存是否可用于初始化,初始化后在*s结尾添加“\0”,然后将缓冲区返回到程序必须是“sds”的一种类型,它是char,因此return语句的结果是return char*sh->buf。希望这一点很清楚,如果你的问题解决了,请投票:)@DanyalImran我找到了这个链接,我现在很清楚:@BlackMamba太棒了:D