您遇到的问题对于您使用指针以及将指针作为 参数 传递给函数时发生的情况更为基本。当您将指针传递给函数(就像任何变量一样)时,函数会收到该指针(或变量)的副本。这意味着当header 传递给myFunc 时,myFunc 会收到header 作为data 的副本(具有自己的,非常不同的地址):
#include <stdio.h>
#include <stdlib.h>
void myFunc(char **data);
int main() {
char **header;
printf ("\n the address of header in main: %p\n", &header);
myFunc(header);
printf("[In main] %s\n", header[1]); // This gives segmentation fault
return 0;
}
void myFunc(char **data) {
data = malloc(2 * sizeof(char *));
printf ("\n the address of data in myFunc: %p\n", &data);
data[0] = "test";
data[1] = "test 2";
printf("[In myFunc] %s\n", data[1]); // This works just fine
}
输出
$ ./bin/myFunc1
the address of header in main: 0x7ffd112e27b8
the address of data in myFunc: 0x7ffd112e2798
[In myFunc] test 2
Segmentation fault
注意:main中header的地址如何是0x7ffd112e27b8,但是当你在myFunc中为data分配内存时,你是在为myFunc分配起始地址指向0x7ffd112e2798 的指针的新内存块。 main 中的任何内容都不知道内存地址 0x7ffd112e2798。
我们如何解决它?
就像您希望将变量传递给函数,更新该变量并将更改的值反映回调用函数(此处为main)时所做的一样 - 您传递 地址的该变量的函数:
#include <stdio.h>
#include <stdlib.h>
void myFunc(char ***data);
int main() {
char **header;
printf ("\n the address of header in main: %p\n", &header);
myFunc(&header); /* passing address of header to myFunc */
printf("[In main] %s\n", header[1]);
return 0;
}
void myFunc(char ***data) {
*data = malloc(2 * sizeof(char *));
printf ("\n the address of data in myFunc: %p\n", data);
(*data)[0] = "test";
(*data)[1] = "test 2";
printf("[In myFunc] %s\n", (*data)[1]);
}
现在您已经将header 的地址传递给myFunc 作为data,当您为*data 分配内存时,您正在分配内存并返回指向相同地址的指针header 在main 中的地址。这允许:
输出
$ ./bin/myFunc2
the address of header in main: 0x7ffdd72b1968
the address of data in myFunc: 0x7ffdd72b1968
[In myFunc] test 2
[In main] test 2
利用来自myFunc的返回
你也可以返回新内存块的起始地址到main并完成同样的事情,例如:
#include <stdio.h>
#include <stdlib.h>
char **myFunc(char **data);
int main() {
char **header;
printf ("\n the address of header in main: %p\n", &header);
header = myFunc(header);
printf("[In main] %s\n", header[1]); // This works fine too
return 0;
}
char **myFunc(char **data) {
data = malloc(2 * sizeof(char *));
printf ("\n the address of data in myFunc: %p\n", &data);
data[0] = "test";
data[1] = "test 2";
printf("[In myFunc] %s\n", data[1]); // This works just fine
return data;
}
输出
$ ./bin/myFunc3
the address of header in main: 0x7ffee22e3298
the address of data in myFunc: 0x7ffee22e3278
[In myFunc] test 2
[In main] test 2
现在main 通过将返回分配给header 知道myFunc 中分配给data 的地址。