4

假设我们有一个 struct :

struct Person {
    char *name;
};

struct Person *Person_create(char *name){
  struct Person *who = malloc(sizeof(struct Person));
  assert(who != NULL);
  who->name = strdup(name);
  return who;
}

void Person_destroy(struct Person *who){
  assert(who != NULL);
  free(who->name);
  free(who);
}

主要功能:

  int main(int argc,char *argv[]){

  struct Person *mike = Person_create("mike");
  Person_print(mike);
  Person_destroy(mike);

  return 0;
}

如果没有 strdup() 函数,上述代码将无法正常工作。Valgrind 说您尝试使用 free(who->name) 释放的地址不是 malloc'd。这背后的故事是什么,当我对结构进行 malloc 时,我没有对内存进行 malloc 吗?strdup() 有什么区别?

4

3 回答 3

5

在您的代码中,每个Person对象都涉及两个独立的内存块:struct Person对象本身和名称的单独内存块。该单独的内存块由name结构内的指针指向。当您struct Person通过 using分配时malloc,您不会为该名称分配任何内存。同样,它是一个独立的内存块,应该独立分配。

您计划如何为名称分配内存完全取决于您。如果您在上面的代码中使用strdup(本质上是一个包装器malloc),那么您将不得不free在最后释放它。

您没有解释“没有 strdup() 函数”的意思。没有它你的代码是什么样子的?如果你只是做了

who->name = name;

然后您将该who->name指针直接指向由 literal 占用的字符串文字内存"mike"。字符串文字驻留在静态内存中。你不允许free他们。这就是 valgrind 告诉你的。

于 2013-08-27T22:41:15.217 回答
0

mallocing struct 为指针 name 分配内存,但它不为 name 指向的内存分配任何内存。那时 who->name 将是一些随机垃圾值,因此释放它没有意义。

strdup 在内部使用 malloc 为其复制的字符串分配内存。一旦你从 strdup 得到一个指针,你就可以而且应该在完成后释放它。

于 2013-08-27T22:43:11.753 回答
-3

strdup 不调用 malloc,它只是字符串操作。你只 malloc 指向结构的指针,而不是内部成员

于 2013-08-27T22:32:58.623 回答