[英]How to return a pointer struct array from a function in C
假设您有一个函数,函数输出将是链表的头和尾地址(将链表复制到另一个地址的函数):
struct path *copyPath(struct path *head) {
struct path *temp = malloc(sizeof (struct path));
// array of newHead and newTail
struct path *resultPath[2];
struct path *newHead = NULL;
struct path *newTail = NULL;
while (head != NULL) {
temp = malloc(sizeof (struct path));
if (newHead == NULL) {
// Add a new node to the first of list and save newHead as the beginning of the list
} else {
// Add the other nodes and save the last node address as newTail
}
head = head -> next;
}
resultPath[0] = newHead;
resultPath[1] = newTail;
return resultPath;
}
我定义了一个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指针。 在下面的行中,您正在将void指针类型的地址分配给struct path类型的指针。
temp = malloc(sizeof(结构路径));
它可以写成:
temp =(结构路径*)malloc(sizeof(结构路径));
第二件事,您正在返回类型为“ struct path”的指针数组,但是您正在使用main违反C标准的main类型为“ struct path”的常规指针收集此指针值的返回数组。 更正此错误,然后尝试运行代码。
在Main中使用指针数组来收集返回值:
结构路径* newPath [2];
newPath = copyPath(path_head,nextNode)
除注释外,您的功能还有两个主要问题:1)通过覆盖分配的第一个内存块的地址来泄漏内存; 和2)您尝试返回returnPath
,该方法具有声明为copyPath
本地的自动存储持续时间。
内存泄漏
通过在分配指针temp
之前覆盖指针temp
,可以在函数中泄漏内存,例如
struct path *temp = malloc(sizeof (struct path));
...
while (head != NULL) {
temp = malloc(sizeof (struct path));
通过在将原始指针分配给另一个变量之前为temp
分配第二次时间,可以丢失temp
指向分配的第一个内存块的原始指针。 从那时起,您的程序将永远无法释放该内存。
返回具有声明为函数局部的自动存储的数组
运行它时,newPath中没有任何内容,它为空。
struct path *resultPath[2];
声明一个指向struct path
的指针数组 (其中两个)。 在函数堆栈框架中,将copyPath
自动存储声明为resultPath
的本地存储。 当copyPath
返回时,具有自动存储持续时间的所有局部变量都将被销毁(释放函数堆栈帧存储器以供重新使用)。 C11标准-§6.2.4对象的存储持续时间明确说明了这一点
1)对象的存储期限决定了其生存期。 有四个存储期限:静态,线程, 自动和已分配。 分配的存储在7.22.3中描述。
2)对象的生存期是程序执行的一部分,在此期间保证为其保留存储空间。 一个对象存在,具有恒定的地址33),并在其整个生命周期中保留其最后存储的值。34) 如果在其生命周期之外引用了一个对象,则该行为是不确定的。 当指针所指向的对象(或刚过去的对象)达到其生命周期的终点时,指针的值将变得不确定。
6)对于这样一个不具有可变长度数组类型的对象,其生存期从进入与之相关联的块开始,直到该块的执行以任何方式结束 。
( 强调我们的 )
那么,什么是返回这些地址的最佳方法?为什么我在newPath中没有它?
为了返回resultPath,您需要为其动态分配存储并返回指向它的指针。 分配了存储时间的对象会延长程序的生命周期,或者直到释放它们为止。
声明和分配能够存储两个指向struct path
指针的对象的最简单方法是,声明一个指向struct path的指针 (实际上是一个动态的指针数组),并为两个指针分配存储空间,例如
/* 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;
现在,您可以安全地return resultPath
并且return resultPath
存储将在返回后resultPath
存在,从而消除了对不再可用的内存的访问。 然后,您分别通过调用者中的newPath[0]
和newPath[1]
访问newHead
和newTail
。
您还需要将copyPath
的返回类型copyPath
为stuct path **
,例如
struct path **copyPath(struct path *head)
并更新呼叫者中的类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.