2014-12-22 167 views
3

我想不起我的问题的正确标题,所以在这里。我正在学习C语言,下面的代码来自我正在学习的教程。复制字符串传递给函数作为参数在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指向提供给函数的​​提供的相同位置。
另外,如果我们直接将​​的地址分配给who->name,那么我们是否需要将其释放到Person_destroy中。

+0

假设你做了who-> name = name,那么你不会修改'who-> name'作为函数参数'name'指向字符串。正如@ al-Acme在他的回答中也解释过的, –

+0

Person_create()是如何调用的。参数'name'从哪里传递?它是如何创建的? – zoska

+1

谢谢大家的回答和评论.. – MiJo

回答

6

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

对我来说这who->name = strdup(name);比这更好who->name = name;如果我知道我会修改由name指出后某处的字符串。

所以,你不妨这样做:

who->name = name; 

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

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

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

你可能想看看:Modifying String Literal

+1

谢谢。有想法。 – MiJo

-2

的字符数组​​不分配的数组,这意味着,如果你离开你的功能范围,该阵列不再可用。因此,本教程将其复制以便稍后在此变量上执行操作。 此外,如果您直接将变量​​指定为who->name,则不得释放它,因为它不是由malloc返回的。

+0

这是不正确的,因为'name'的值仍然可以使用。只要对变量的任何引用都是无效的,而不是价值。 –

+0

@PhilippMurry关于如果它被直接赋值为name的地址,那么释放who-> name是真的吗?正如@ al-Acme的回答中所提到的,原来的'name'不在堆上。 – MiJo

+0

如果它不在堆上,那就是这样。作为一个经验法则:对于每次调用malloc/calloc,都必须有一个空闲的调用。不多也不少。因此,如果它不在堆上,则永远不会有对malloc/calloc的调用,因此不需要调用free。 –

相关问题