我正在尝试学习如何使用sds功能。我在我的项目文件夹中有代码sds.h和sds.c代码文件,我编写的小探索程序编译并运行得很好。但是,我很难理解我在sds.h和sds.c文件的代码中看到的一些内容。我不知道为什么它编译,更不用说工作了。
有问题的代码是:
typedef char *sds;
struct sdshdr {
int len;
int free;
char buf[];
};
static inline size_t sdslen(const sds s) {
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
return sh->len;
}
sdslen()函数在sds.c文件中被多次调用,我甚至可以在包含sds.h之后在我自己的程序中使用它。我知道typedef使sds成为一个只是char指针的类型。 static关键字限制了函数的范围。内联意味着编译器在调用函数时将函数粘贴到代码中,而不是使用堆栈和函数调用机制。 在我看来,sdslen()函数中的* sh指针在存储在s中的地址之前被分配了一个地址sizeof(struct sdshdr)内存地址,然后没有初始化结构中的任何变量,len成员变量被传回。 任何帮助理解这一点,真正发生的事情,将不胜感激。
答案 0 :(得分:1)
我想我明白了。答案来自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;
}
当创建新sds
并由sdsnewlen()
函数初始化时,将为整个结构和c-string动态分配内存,但c-string的地址将被传回。如果使用sdslen()
变量调用了sds
malloc
而未使用sdsnewlen()
函数,则会导致问题。只要使用提供的函数初始化sds
变量,则内存有效,成员变量已初始化,sds
变量可用于printf()
之类的内容因为任何c-string都可以。