这是一个查询,以了解以下代码即使有错误也能正常工作。
据我所知,如果我想重新分配/重新分配传递给函数的指针,则该指针需要作为双指针传递。错误地,我传递了一个指针,程序仍在工作。我猜想它必须在指针是字符串的情况下执行某些操作。
程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func2( char **x){
printf("befor func2 x = %u; *x = %u; **x = %s; x_size = %u\n", x, *x, *x, strlen(*x));
free(*x);
*x = (char *)malloc(20);
strcpy(*x, "zyxwvutsrqponmlkjih");
printf("\n\nafter func2 x = %u; *x = %u; **x = %s; x_size = %u\n", x, *x, *x, strlen(*x));
}
void func1( char *x){
printf("befor func1 &x = %u; x = %u; *x = %s; x_size = %u \n", &x, x, x, strlen(x));
func2(&x);
printf("after func1 &x = %u; x = %u; *x = %s; x_size = %u \n", &x, x, x, strlen(x));
}
int main(){
char *x;
x = (char *)malloc(10);
strcpy(x, "abcdefghi");
printf("befor main &x = %u; x = %u; x = %s; x_size = %u\n", &x, x, x, strlen(x));
func1(x);
printf("after main &x = %u; x = %u; x = %s; x_size = %u\n", &x, x, x, strlen(x));
free(x);
return 1;
}
输出:
befor main &x = 489275896; x = 20414480; x = abcdefghi; x_size = 9
befor func1 &x = 489275864; x = 20414480; *x = abcdefghi; x_size = 9
befor func2 x = 489275864; *x = 20414480; **x = abcdefghi; x_size = 9
after func2 x = 489275864; *x = 20414480; **x = zyxwvutsrqponmlkjih; x_size = 19
after func1 &x = 489275864; x = 20414480; *x = zyxwvutsrqponmlkjih; x_size = 19
after main &x = 489275896; x = 20414480; x = zyxwvutsrqponmlkjih; x_size = 19
我可以理解直到func1
为止的输出。但是在main
中进行修改后,大小和值如何返回到func2
?我没有将x
作为双指针从main
传递到func1
。但是不知何故它仍在工作。是因为它是char *
吗?
编辑1:
在注释中建议的编辑后:
程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func2( char **x){
printf("befor func2 x = %p; *x = %p; **x = %s; x_size = %u\n", x, *x, *x, strlen(*x));
free(*x);
*x = (char *)malloc(20);
strcpy(*x, "zyxwvutsrqponmlkjih");
printf("\n\nafter func2 x = %p; *x = %p; **x = %s; x_size = %u\n", x, *x, *x, strlen(*x));
}
void func1( char *x){
printf("befor func1 &x = %p; x = %p; *x = %s; x_size = %u \n", &x, x, x, strlen(x));
func2(&x);
printf("after func1 &x = %p; x = %p; *x = %s; x_size = %u \n", &x, x, x, strlen(x));
}
int main(){
char *x, *y, *z;
x = (char *)malloc(10);
z = (char *)malloc(100);
y = (char *)malloc(100);
strcpy(x, "abcdefghi");
printf("befor main &x = %p; x = %p; x = %s; x_size = %u\n", &x, x, x, strlen(x));
func1(x);
printf("after main &x = %p; x = %p; x = %s; x_size = %u\n", &x, x, x, strlen(x));
free(x);
free(y);
free(z);
return 1;
}
输出:
befor main &x = 0x7fff78cb09c8; x = 0x1c7a010; x = abcdefghi; x_size = 9
befor func1 &x = 0x7fff78cb09a8; x = 0x1c7a010; *x = abcdefghi; x_size = 9
befor func2 x = 0x7fff78cb09a8; *x = 0x1c7a010; **x = abcdefghi; x_size = 9
after func2 x = 0x7fff78cb09a8; *x = 0x1c7a010; **x = zyxwvutsrqponmlkjih; x_size = 19
after func1 &x = 0x7fff78cb09a8; x = 0x1c7a010; *x = zyxwvutsrqponmlkjih; x_size = 19
after main &x = 0x7fff78cb09c8; x = 0x1c7a010; x = zyxwvutsrqponmlkjih; x_size = 19
[程序在引入多个malloc之后仍然可以工作。
您似乎认为使用char *x
(单个指针)作为func1
的参数是一个错误。但是,我认为这很好。 func1
期望将char指针作为参数,或者基本上是将其取消引用时给出char或一堆char的内存地址。当您在main中写入func1(x);
时,您正在传递x,即一堆字符的地址,这正是参数func1
所期望的类型。
为什么x是一堆字符的地址?在这种情况下,指针x
正在存储(字符)数组的地址。现在,您可能知道,如果只写一个数组的名称,就可以得到该数组的基地址。参见下面的代码:
#include <stdio.h>
#include <stdlib.h>
int main () {
int arr[5] = {1, 2, 3, 4, 5};
printf ("%d\n", arr); // address of the first element (1) of the array
// or, the base address of the array
printf ("%d\n", &arr[0]); // same as above
printf ("%d\n\n", *arr); // gives the first element of the array
int *x = malloc (5*sizeof (int));
*x = 1;
*(x+1) = 2;
*(x+2) = 3;
*(x+3) = 4;
*(x+4) = 5;
printf ("%d\n", x); // address of the first element (1) of the array
// or, the base address of the array
printf ("%d\n", &*(x+0)); // same as above
printf ("%d\n\n", *x); // gives the first element of the array
return 0;
}
输出如下:
6356712
6356712
1
9768168
9768168
1
现在,为什么我们能够修改x指向的字符数组中的值?因为我们已经传递了该数组的基地址。我们可以取消引用该地址以访问该数组并对其执行任何操作。