C 从另一个函数中的指针检索值时出现分段错误
我是C的初学者,遇到了以下问题:C 从另一个函数中的指针检索值时出现分段错误,c,pointers,C,Pointers,我是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 giv
#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
}
#包括
#包括
#包括
#包括
void myFunc(字符**数据);
int main(){
字符**头;
myFunc(标题);
printf(“[In main]%s\n”,头[1]);//这会导致分段错误
返回0;
}
void myFunc(字符**数据){
数据=(字符**)malloc(2*sizeof(字符*);
数据[0]=“测试”;
数据[1]=“测试2”;
printf(“[In myFunc]%s\n”,数据[1]);//这很好用
}
我可以在我为指针分配内存的函数中检索并打印指针的值,但在此之外(在main中),它会导致分段错误。原则上,您需要在调用函数之前分配
数据。相反,通过在函数内部分配数据
,它在函数内部是已知的,但在main
中是未知的
在这种情况下,您需要:
- 在调用
myFunc()
之前,为数据分配内存(在该函数内部,您不需要为数据分配内存)
:
header=(char**)malloc(2*sizeof(char*)代码>
myFunc(标题)代码>
- 在
myFunc()
中,使用字符串文字时,不需要为指向char的两个指针分配内存:
数据[0]=“测试”代码>
但是,也可以为单个字符指针分配内存:
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;
}
您遇到的问题是,指针的使用更为基本,当您将指针作为参数传递给函数时会发生什么。当您向函数传递指针(就像任何变量一样)时,函数将收到该指针(或变量)的副本。这意味着当标题
传递给myFunc
时,myFunc
会收到一份标题
的副本,作为数据
(其地址非常不同):
注意:在main
中头的地址如何是0x7ffd112e27b8
,但是当您为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]);
}
使用来自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;
}
现在main
知道了myFunc
中分配给data
的地址,通过将返回值分配给标题
谢谢,这就解决了它!澄清一下,一旦我将内存传递到函数中,我可以为函数中的数组元素分配更多内存吗?像这样的数据[0]=(char*)malloc(15*sizeof(char));我认为您需要两个级别的内存分配;在main
中,为头分配内存(它是指向char的指针)。在myFunc
中,您需要为单个字符指针进行分配。完全没有理由复制字符串。在上面的例子中,使用直接赋值是完全可以的。OP代码的问题在于缺少更直接的赋值:实际的错误在于未能从myFunc
返回值,因此标题
从未实际设置。Ok,在直接赋值的特定点上,我的错误-编辑了它。除此之外,答案中的内存分配是否有问题?你能发布一个不同的答案来阐明你的观点吗。无需在myFunc
之外分配内存。您可以从函数返回分配的内存:OP的错误在于没有返回要分配给头的值。这就是全部;你对这个问题考虑得太多了。要使它干净地编译,请更改:char**header
到'char**header=NULL;在C语言中,调用malloc()
,1)时不要强制转换返回值,因为它是一个void*
,因此可以分配给任何其他指针。强制转换只会使代码变得混乱,并给代码的调试和维护带来麻烦。2) 在使用返回值之前,始终检查(!=NULL)以确保操作成功。此类行:data[0]=“test”代码>需要:(*数据)[0]=“测试”代码>此行:myFunc(表头)
传递头的内容
需要传递的是头的地址:myFunc(&header)代码>此行:data=(char**)malloc(2*sizeof(char*)代码>未将标题的内容设置为指向malloc'd区域。它应该是:*data=malloc(2*sizeof(char*))代码>当然,还要检查*数据=实际使用指针之前为NULL
#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]);
}
$ ./bin/myFunc2
the address of header in main: 0x7ffdd72b1968
the address of data in myFunc: 0x7ffdd72b1968
[In myFunc] test 2
[In main] test 2
#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