【问题标题】:Duplicating strings passed to functions as parameters in C在 C 中复制作为参数传递给函数的字符串
【发布时间】:2014-12-22 08:58:11
【问题描述】:

我想不出我的问题的合适标题,所以就这样吧。我正在尝试学习 C,以下代码来自我正在学习的教程。

struct Person {
    char *name;
    int age;
    int height;
    int weight;
};

struct Person *Person_create(char *name, int age, int height, int weight){
    struct Person *who = malloc(sizeof(struct Person));
    assert(who != NULL);

    who->name = strdup(name);
    who->age = age;
    who->height = height;
    who->weight = weight;

    return who;
}

void Person_destroy(struct Person *who){
    assert(who != NULL);

    free(who->name);
    free(who);
}

int main(int argc, char *argv[]){
    struct Person *joe = Person_create("Joe Alex", 32, 64, 140);

    ........

我的问题是在 Person_create 函数中,为什么我们要将 name 复制到 who->name 的新内存位置。为什么我们不能让who->name 指向由提供给函数的*name 提供的相同位置。
另外,如果我们直接将*name的地址分配给who->name,我们是否必须在Person_destroy中释放它。

【问题讨论】:

  • 假设如果你做了who->name = name,那么你不能修改who->name后者作为函数参数name指向字符串文字。正如@al-Acme 在他的回答中所解释的那样,
  • 如何调用 Person_create()。参数name 是从哪里传递过来的?它是如何创建的?
  • 谢谢大家的回答和cmets..
  • 只是一个建议:您可能想稍微改进一下您的问题标题。它实际上并没有反映您的问题。
  • @zoska 它已经在那里了。 Person_create("Joe Alex", 32, 64, 140);

标签: c string struct strdup


【解决方案1】:

为什么我们不能让 who->name 指向函数提供的 *name 提供的相同位置。

对我来说,这个who->name = strdup(name); 比这个who->name = name; 更好,如果我知道我稍后会修改name 指向的字符串。

所以你不妨这样做:

who->name = name;

但是,像 "Joe Alex" 这样的字符串文字位于只读位置 - 所以如果你想做这样的事情(稍后在你的代码的某些部分):

who->name[3] = 'x';

你会得到分段错误。因此,如果你想修改它,你想从堆中 malloc 一些 可写 空间 strdup 为你做的。

您可能想看看:Modifying String Literal

【讨论】:

  • 谢谢。明白了。
【解决方案2】:

char 数组*name 不是一个分配的数组,这意味着如果你离开你的函数作用域,这个数组就不再可用了。因此本教程复制它以便稍后对此变量进行操作。 此外,如果您直接将变量*name 分配给who->name,则不能释放它,因为它不是由 malloc 返回的。

【讨论】:

  • 这不是真的,因为name 的值仍然可以使用。只是对变量的任何引用都是无效的,而不是它的值。
  • @PhilippMurry 如果who->name 直接分配了name 的地址,那么关于它不释放的位是真的吗?正如@al-Acme 的回答中提到的,原来的name 不在堆上。
  • 如果它不在堆上,那就是真的。根据经验:每次调用 malloc/calloc 时,必须调用一次 free。不多也不少。因此,如果它不在堆上,则永远不会调用 malloc/calloc,因此不需要调用 free。
猜你喜欢
  • 2010-10-03
  • 1970-01-01
  • 2018-06-26
  • 2020-12-19
  • 2017-04-25
  • 2015-12-31
  • 1970-01-01
  • 2012-11-15
相关资源
最近更新 更多