简体   繁体   English

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

[英]Pointers, valid memory addresses, and understanding the sds library

I am trying to learn how to use the sds functions. 我正在尝试学习如何使用sds函数。 I have the code sds.h and sds.c code files in my project folder and the little exploration program that i wrote compiles and runs just fine. 我在项目文件夹中有代码sds.h和sds.c代码文件,而我编写的小探索程序可以编译并运行良好。 However I am having a hard time understanding some of what I am seeing in the code from the sds.h and sds.c files. 但是,我很难理解sds.h和sds.c文件中的代码。 I can't tell why it compiles let alone works. 我不知道为什么它不能编译工作。

The code in question is: 有问题的代码是:

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;
}

The sdslen() function is called numerous times in the sds.c file and I can even use it in my own program after including the sds.h. sdslen()函数在sds.c文件中被调用了很多次,在包含sds.h之后,我什至可以在自己的程序中使用它。 I know that the typedef makes sds a type that is just a char pointer. 我知道typedef使sds只是一个char指针。 The static keyword restricts the scope of the function. static关键字限制了函数的范围。 Inline means that the function will be pasted into the code by the compiler when it is called rather then using the stack and function call mechanisms. 内联意味着函数将在被调用时由编译器粘贴到代码中,而不是使用堆栈和函数调用机制。 It looks to me like the *sh pointer in the sdslen() function is assigned an address sizeof(struct sdshdr) memory addresses before the address stored in s and then without initializing any of the variables in the struct the len member variable is passed back. 在我看来,sdslen()函数中的* sh指针在存储在s中的地址之前被分配了一个地址sizeof(struct sdshdr)内存地址,然后不初始化struct中的任何变量,就将len成员变量传回了。 Any help in understanding this, what is really happening, would be appreciated. 我们将不胜感激,以帮助您了解实际情况。

I think I figured it out. 我想我知道了。 The answer is in another function from the sds.c file: 答案在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;
}

When a new sds is created and initialized by the sdsnewlen() function memory is dynamically allocated for the entire struct and the c-string but the address of the c-string is what gets passed back. 当通过sdsnewlen()函数创建并初始化新的sds会为整个结构和c字符串动态分配内存,但是c字符串的地址才传回。 If sdslen() were called with a sds variable that had been allocated using malloc without using the sdsnewlen() function it would cause a problem. 如果sdslen()用一个叫做sds已被使用分配变量malloc不使用sdsnewlen()函数会引起一个问题。 As long as the sds variables are initialized using the provided functions then the memory is valid, the member variables have been initialized and the the sds variable can be used in things like printf() the same as any c-string could be. 只要使用提供的函数初始化sds变量,然后内存就有效,成员变量已经初始化,并且sds变量可用于诸如printf()之类的东西,与任何c字符串一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM