1

我正在尝试学习如何使用 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) 内存地址,然后在不初始化 struct 中的任何变量的情况下,将 len 成员变量传回. 任何有助于理解这一点,真正发生的事情,将不胜感激。

4

1 回答 1

2

我想我想通了。答案在文件中的另一个函数中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()的变量调用而不使用该函数,则会导致问题。只要变量是使用提供的函数初始化的,那么内存是有效的,成员变量已经被初始化并且变量可以像任何 c-string 一样被使用。sdsmallocsdsnewlen()sdssdsprintf()

于 2013-11-06T18:47:47.443 回答