Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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_Arrays_Function_Linked List - Fatal编程技术网

如何从C中的函数返回指针结构数组

如何从C中的函数返回指针结构数组,c,arrays,function,linked-list,C,Arrays,Function,Linked List,假设您有一个函数,函数输出将是链接列表的头和尾地址(用于在另一个地址复制链接列表的函数): 我定义了一个struct path数组并返回它。在主函数中定义了一个数组: struct path *newPath; newPath = copyPath(path_head, nextNode); 当我运行它时,我在newPath中没有任何内容,它是空的 那么,返回这些地址的最佳方式是什么?为什么我在newPath中没有它 此外,当我使用: struct path *newPath[2]; newP

假设您有一个函数,函数输出将是链接列表的头和尾地址(用于在另一个地址复制链接列表的函数):

我定义了一个
struct path
数组并返回它。在主函数中定义了一个数组:

struct path *newPath;
newPath = copyPath(path_head, nextNode);
当我运行它时,我在newPath中没有任何内容,它是空的

那么,返回这些地址的最佳方式是什么?为什么我在
newPath
中没有它

此外,当我使用:

struct path *newPath[2];
newPath = copyPath(path_head, nextNode);
我有一个错误:
error:assignment to expression with array type


如何将这两个值传递给主函数?

每当分配动态内存(使用malloc、calloc、realloc)时,请将返回地址适当地键入到正确的数据类型。因为这些函数返回空指针。在下一行中,您将为结构路径类型指针指定void指针类型地址

temp=malloc(sizeof(struct path))

它可以写成:

temp=(结构路径*)malloc(sizeof(结构路径))

第二件事,您返回的是一个类型为“struct path”的指针数组,但您在main中的一个类型为“struct path”的常规指针中收集指针值的返回数组,这与C标准不符。更正此错误并尝试运行代码

主要使用指针数组来收集返回值:

结构路径*newPath[2]


newPath=copyPath(path\u head,nextNode)

无论何时分配动态内存(使用malloc、calloc、realloc),都要将返回地址适当地类型转换为正确的数据类型。因为这些函数返回空指针。在下一行中,您将为结构路径类型指针指定void指针类型地址

temp=malloc(sizeof(struct path))

它可以写成:

temp=(结构路径*)malloc(sizeof(结构路径))

第二件事,您返回的是一个类型为“struct path”的指针数组,但您在main中的一个类型为“struct path”的常规指针中收集指针值的返回数组,这与C标准不符。更正此错误并尝试运行代码

主要使用指针数组来收集返回值:

结构路径*newPath[2]


newPath=copyPath(path\u head,nextNode)

除了注释之外,您的函数还有两个主要问题:1)您通过覆盖第一个分配内存块的地址泄漏内存;2)尝试返回
returnPath
,该路径的自动存储持续时间声明为本地
copyPath

内存泄漏

在指定指针之前覆盖指针
temp
,导致函数内存泄漏,例如:

struct path *temp = malloc(sizeof (struct path));  
...
while (head != NULL) {
    temp = malloc(sizeof (struct path));
在将原始指针分配给另一个变量之前,通过为
temp
分配第二次,将丢失指向分配的第一个内存块的
temp
中的原始指针。从这一点开始,程序永远无法释放内存

返回声明为本地功能的自动存储阵列

当我运行它时,我在newPath中没有任何内容,它是空的


struct path*resultPath[2]
声明指向
结构路径的指针数组(其中两个)。
resultPath
的自动存储被声明为其函数堆栈框架内的
copyPath
本地存储。当
copyPath
返回时,所有具有自动存储持续时间的本地变量都将被销毁(函数堆栈帧内存将被释放以供重用)。这一点由

1)对象的存储持续时间决定其生存期。有四个存储持续时间:静态、线程、自动和已分配。中描述了分配的存储

2)对象的生存期是程序执行期间保证为其保留存储的部分。对象存在,具有恒定地址33),并在其整个生存期内保留其最后存储的值。34)如果对象在其生存期之外被引用,则行为未定义。当指针指向(或刚刚经过)的对象到达其生命周期结束时,指针的值将变得不确定

6)对于没有可变长度数组类型的对象,其生存期从进入与其关联的块开始,一直到该块的执行以任何方式结束

(我们的重点)

那么,返回这些地址的最佳方式是什么?为什么我在newPath中没有这些地址

为了返回resultPath,您需要动态地为它分配存储并返回指向它的指针。具有已分配存储持续时间的对象将在程序的生命周期内或直到释放为止

为能够存储指向结构路径的两个指针的对象声明和分配最简单的方法是声明指向结构路径指针的指针(实际上是指针的动态数组),并为两个指针分配存储,例如

/* allocate & validate 2 pointers to struct path */
struct path **resultPath = malloc (sizeof *resultPath * 2);
if (!resultPath) {        /* always validate all memory allocations */
    perror ("malloc resultPath failed.");
    return NULL;
}
...
resultPath[0] = newHead;  /* newHead & newTail must point to allocated memory */
resultPath[1] = newTail;        

return resultPath;
您现在可以安全地
返回resultPath
,并且
resultPath
的存储将在返回后继续生存,从而消除对不再可用的内存的访问。然后分别通过调用方中的
newPath[0]
newPath[1]
访问
newHead
newTail

您还需要将
copyPath
的返回类型更改为
stuct path**
,例如

struct path **copyPath(struct path *head)

和更新调用者中的类型。

除了注释之外,您的函数还有两个主要问题:1)您通过覆盖第一个分配的内存块的地址泄漏内存;2)尝试返回
returnPath
,该路径的自动存储持续时间声明为本地
copyPath

内存
struct path **copyPath(struct path *head)