使用strdup()或strcpy()进行说明

时间:2016-04-23 16:38:43

标签: c

我有一个问题 这个方法工作正常,它返回一个具有正确NaME值的结构

prodotti creaProdotto(char *name, float price, prodotti next){
    prodotti p = malloc(sizeof(prodotti));
    p->name = malloc(30 * sizeof(char));
    p->name = strdup( name);
    p->price = price;
    p->next = next;
    return p;
}

否则这不起作用,

prodotti creaProdotto(char *name, float price, prodotti next){
    prodotti p = malloc(sizeof(prodotti));
    p->name = malloc(30 * sizeof(char));
    strcpy(p->name, name);
    p->price = price;
    p->next = next;
    return p;
}

第二个问题是:name不包含正确的值, 请解释为什么。

2 个答案:

答案 0 :(得分:2)

假设prodotti被typedefed作为指针类型,你就会遇到一个根本问题(在这两种情况下):

    prodotti p = malloc(sizeof(prodotti));

您只为一个指针分配足够的空间,而不是为指向的东西。因此,当您分配给*p的成员时,您调用未定义的行为,其推定的存储从对象的开头进一步延伸,而不是指针的大小。

这种混淆是避免将指针性质隐藏在typedef后面的一个很好的理由。但是,完成此操作后,您可以避免显式引用typedef背后的实际类型,如下所示:

    prodotti p = malloc(sizeof(*p));

在任何情况下,这都是一个很好的模式,因为它可以抵御指向类型的变化。

由于你在两种情况下都有未定义的行为,因此推测实际发生的事情是毫无意义的,因为推测是我们从语言角度可以做到的。这就是“未定义”的含义。

此外,正如其他人所观察到的那样,对malloc()的{​​{1}}内存来说,它比没有意义,然后用结果p->name覆盖结果指针。然后,您不仅会分配比您需要的内存更多的内存,而且还会泄漏通过strdup()获得的内存。似乎malloc()本身没有前面的strdup(),这将是一种合理的方法。

答案 1 :(得分:1)

我们没有太多信息可以帮助您了解详情,但是:

  1. 似乎prodotti属于指针类型,因此您没有为完整结构分配内存,仅为指针分配内存。使用malloc(sizeof *prodotti)
  2. strdup分配了内存并复制了c-string
  3. strcpy只需将给定c-string的内容复制到给定的内存
  4. 如果使用strdup,则分配内存无用。

    您可能在第二种情况下分配的内存不多,因此遇到某种缓冲区溢出(取决于您使用的字符串)。使用标准惯用语:p->name = malloc(strlen(name)+1); strcpy(p->name,name);

    您必须在其他任何事情之前纠正n°1点...始终验证分配是否成功。