[英]Segmentation Fault when retrieving value from pointer in another function
I'm a beginner with C and am running into the following problem: 我是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
}
I can retrieve and print the value of the pointer within the function I allocated the memory for it, but outside of this (in main), it gives segmentation fault. 我可以在为其分配内存的函数中检索和打印指针的值,但在此之外(在main中),它会给出分段错误。
The issue you are having is a little more fundamental to your use of pointers and what happens when you pass a pointer as an argument to a function. 您遇到的问题对于使用指针更为重要,以及将指针作为参数传递给函数时会发生什么。 When you pass a pointer to a function (just like any variable), the function receives a copy of that pointer (or variable).
当您将指针传递给函数时(就像任何变量一样),该函数会接收该指针(或变量)的副本 。 Meaning that when
header
is passed to myFunc
, myFunc
receives a copy of header
as data
(with its very own, and very different, address ): 这意味着当
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
}
Output 产量
$ ./bin/myFunc1
the address of header in main: 0x7ffd112e27b8
the address of data in myFunc: 0x7ffd112e2798
[In myFunc] test 2
Segmentation fault
Note: how the address of header
in in main
is 0x7ffd112e27b8
, but when you allocate memory for data
in myFunc
, you are assigning the starting address for the new block of memory to a pointer at 0x7ffd112e2798
. 注意:
main
的header
的地址如何是0x7ffd112e27b8
,但是当你为myFunc
data
分配内存时,你将新的内存块的起始地址分配给0x7ffd112e2798
的指针。 Nothing in main
knows anything about memory address 0x7ffd112e2798
. main
知道内存地址0x7ffd112e2798
没有任何内容。
How Do We Fix it? 我们如何解决这个问题?
Just like you do every other time you wish to pass a variable to a function, update that variable, and have the changed value reflected back in the calling function ( main
here) -- you pass the address of that variable to the function: 就像你每次都希望将变量传递给函数一样,更新该变量,并将更改后的值反映回调用函数(此处为
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]);
}
Now that you have passed the address of header
to myFunc
as data
, when you allocate memory for *data
, you are allocating memory and returning the pointer to the same address for header
in main
. 现在您已将
header
的地址作为data
传递给myFunc
,当您为*data
分配内存时,您正在分配内存并将指针返回到main
header
的相同地址。 Which allows: 这使得:
Output 产量
$ ./bin/myFunc2
the address of header in main: 0x7ffdd72b1968
the address of data in myFunc: 0x7ffdd72b1968
[In myFunc] test 2
[In main] test 2
Making Use of the Return from myFunc
利用
myFunc
返回
You can also return the starting address for the new block of memory to main
and accomplish the same thing, eg: 您还可以将新内存块的起始地址返回到
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;
}
Output 产量
$ ./bin/myFunc3
the address of header in main: 0x7ffee22e3298
the address of data in myFunc: 0x7ffee22e3278
[In myFunc] test 2
[In main] test 2
Now main
knows about the address allocated to data
in myFunc
by virtue of assigning the return to header
. 现在
main
通过将返回分配给header
了解分配给myFunc
data
的地址。
In principle, you need to allocate the data
before calling a function to work on it. 原则上,您需要在调用函数之前分配
data
以对其进行处理。 You did it the other way around, by allocating data
inside the function, it is known inside the function itself but not in main
. 你反过来做了,通过在函数内部分配
data
,它在函数本身内部而不是在main
已知。
In this particular case, you need to: 在这种特殊情况下,您需要:
data
before calling myFunc()
(inside that function itself you don't need to allocate the memory for data
): myFunc()
之前为data
分配内存(在该函数本身内部,您不需要为data
分配内存): header = (char **)malloc(2 * sizeof(char *));
myFunc(header);
myFunc()
, there is no need to allocate memory for the two pointers to char as you are using string literals: myFunc()
,当你使用字符串文字时,不需要为char的两个指针分配内存: data[0] = "test";
However, it is possible to allocate memory for individual char pointer as well: 但是,也可以为单个char指针分配内存:
data[0] = (char *)malloc(15 * sizeof(char));
In that case, you can do strcpy
or some other methods to set the content of data[0]
and data[1]
在这种情况下,您可以使用
strcpy
或其他一些方法来设置data[0]
和data[1]
Alternatively, all allocation can be done inside myFunc()
, but you need to change the prototype to return the proper pointer. 或者,所有分配都可以在
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.