strdup()的用法

问题描述 投票:0回答:3

假设我们有一个结构:

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
ed。这背后的故事是什么,我在
malloc
编辑该结构时不是有
malloc
的记忆吗?
strdup()
有什么区别?

c struct segmentation-fault free
3个回答
5
投票

在您的代码中,每个

Person
对象都涉及两个独立的内存块:
struct Person
对象本身和名称的单独内存块。该单独的内存块由结构内部的
name
指针指向。当您使用
struct Person
分配
malloc
时,您没有为该名称分配任何内存。同样,它是一个独立的内存块,应该独立分配。

您计划如何为名称分配内存完全取决于您。如果您像上面的代码一样使用

strdup
(本质上是
malloc
的包装),那么您最终必须通过
free
释放它。

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

who->name = name;

然后您使

who->name
指针直接指向文字
"mike"
占用的字符串文字内存。字符串文字驻留在静态内存中。您不可以
free
他们。这就是 valgrind 告诉你的。


0
投票

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

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


-3
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.