我是C的初学者,遇到了以下问题:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
void myFunc(char **data);
int main() {
char **header;
myFunc(header);
printf("[In main] %s\n", header[1]); // This gives segmentation fault
return 0;
}
void myFunc(char **data) {
data = (char **)malloc(2 * sizeof(char *));
data[0] = "test";
data[1] = "test 2";
printf("[In myFunc] %s\n", data[1]); // This works just fine
}
我可以在为其分配内存的函数中检索和打印指针的值,但在此之外(在main中),它会给出分段错误。
答案 0 :(得分:3)
您遇到的问题对于指针的使用更为重要,以及将指针作为参数传递给函数时会发生什么。当您将指针传递给函数(就像任何变量一样)时,该函数会接收该指针(或变量)的副本。这意味着当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
注意: header
中main
的地址如何0x7ffd112e27b8
,但在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
你也可以将1}}新内存块的起始地址返回并完成同样的事情,例如:
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
,了解分配给data
中myFunc
的地址。
答案 1 :(得分:1)
原则上,您需要在调用函数之前分配data
以进行处理。你反过来做了,通过在函数内部分配data
,它在函数本身内部已知,但在main
中却不知道。
在这种特殊情况下,您需要:
data
之前为myFunc()
分配内存(在该函数内部,您不需要为data
分配内存): header = (char **)malloc(2 * sizeof(char *));
myFunc(header);
myFunc()
内部,当你使用字符串文字时,不需要为char的两个指针分配内存: data[0] = "test";
但是,可能也为单个char指针分配内存:
data[0] = (char *)malloc(15 * sizeof(char));
在这种情况下,您可以执行strcpy
或其他一些方法来设置data[0]
和data[1]
的内容
或者,所有分配都可以在myFunc()
内完成,但您需要更改原型以返回正确的指针。
char** myFunc() {
char **data = (char **)malloc(2 * sizeof(char *));
data[0] = "test";
data[1] = "test 2";
printf("[In myFunc] %s\n", data[1]);
return data;
}
int main() {
char **header;
header = myFunc();
printf("[In main] %s\n", header[1]);
return 0;
}