指针,有效的内存地址,以及了解sds库

时间:2013-11-06 18:09:44

标签: c

我正在尝试学习如何使用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成员变量被传回。 任何帮助理解这一点,真正发生的事情,将不胜感激。

1 个答案:

答案 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都可以。