指向指针和strcpy的函数

时间:2016-10-30 07:17:37

标签: c function pointers

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void Get_Text(char *string);
void Get_Text_Double(char **string);
void String_Copy(char *string);

int main(void) {
    char *name = malloc(10 * sizeof(char));
    char *name2 = malloc(10 * sizeof(char));
    char *name3 = malloc(10 * sizeof(char));

    Get_Text(name);
    printf("\n%s\n", name);

    Get_Text_Double(&name2);
    printf("\n%s\n", name2);

    String_Copy(name3);
    printf("\n%s\n", name3);

    return 0;
}

void Get_Text(char *string) {
    string = "test";
}

void Get_Text_Double(char **string) {
    *string = "test2";
}

void String_Copy(char *string) {
    strcpy(string, "test3");
}

在上面的代码中,为什么Get_Text_DoubleString_Copy函数有效,Get_Text函数没有?

为什么String_Copy函数只能使用单个指针而不是像Get_Text_Double那样的双指针?

2 个答案:

答案 0 :(得分:7)

Get_Text函数不起作用,因为它只更改传递给它的指针的副本。函数退出后,它将丢失。 =运算符无论如何都不能复制字符串,只能复制指针的值。这样一行

printf("\n%s\n", name);

导致未定义的行为,因为分配给name的内存尚未初始化。

在下一个函数Get_Text_Double中,指针的位置被传递。它由指向字符串文字的指针替换,覆盖从malloc获得的指针。所以现在不可能free(name2)

在最后一个函数String_Copy中,库函数strcpy用于将字符串文字复制到为name3获取的内存中。

最后一个函数是三者中唯一的一个,它实际上将一个字符串复制到提供的内存中。另外两个只将指针复制到一个字符串,在第一个例子中丢失了。

修改

在使用单个*的第三种情况下,传递一个指针 - name3,它指向已分配的内存。这传递给strcpy,它将字符串文字复制到指向的内存。

但是**的第二个函数传递了一个指向的指针,所以不是传递已分配内存的地址,而是传递的地址指针本身。请注意,它是用

调用的
Get_Text_Double(&name2)

具有&地址运算符,其他2个函数缺少。

所以当你写入*string时,你正在改变实际指针name2本身的值,而不是它所分配的内存。

因此,name2现在将指向您的字符串文字"test2",并且未复制任何文字。现在,您已更改指针,并且无法将其新值传递给free,因为您无法free字符串文字。您只能使用free最初返回的指针值来malloc内存,这是您无法做到的,因为name2已被覆盖。

答案 1 :(得分:1)

你也可以不用函数重写它:

char *name1 = malloc(10 * sizeof(char));
char *name2 = malloc(10 * sizeof(char));
char *name3 = malloc(10 * sizeof(char));

char *string1 = name1;
string1 = "t1";
printf("%s\n", name1);

char **string2 = &name2;
*string2 = "t2";
printf("%s\n", name2);

char *string3 = name3;
strcpy(string3, "t3");
printf("%s\n", name3);

在第一个示例中,string1 = "t1"表示string1不再指向name1。这不会更改name1,因此name1仍然未初始化,当您打印name1时,它会显示随机字符。

在第二个示例中,我们可以将*string2 = "t2"重写为*(&name2) = "t2",而*(&name2)只是name2。这可以简化为:

name2 = "t2";

打印name2会显示"t2",但现在您无法释放分配了malloc的内存

第三个示例是使用name3填充"t3"并且没问题。