#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_Double
和String_Copy
函数有效,Get_Text
函数没有?
为什么String_Copy
函数只能使用单个指针而不是像Get_Text_Double
那样的双指针?
答案 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"
并且没问题。