Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从另一个函数中的指针检索值时出现分段错误_C_Pointers - Fatal编程技术网

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

我是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
}
#包括
#包括
#包括
#包括
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