假设您有一个函数,函数输出将是链表的头地址和尾地址(用于将链表复制到另一个地址的函数):
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);
我有一个错误:错误:赋值给数组类型的表达式
如何将这两个值传递给主函数?
最佳答案
除了注释之外,您的函数还有两个主要问题,1) 您通过覆盖第一个分配的内存块的地址来泄漏内存;和 2) 您尝试返回 returnPath
,它具有在 copyPath
本地声明的自动存储持续时间。
内存泄漏
您通过在分配指针 temp
之前覆盖它来泄漏函数中的内存,例如
struct path *temp = malloc(sizeof (struct path));
...
while (head != NULL) {
temp = malloc(sizeof (struct path));
通过在将原始指针分配给另一个变量之前为 temp
分配第二次,您将丢失 temp
中指向分配的第一个内存块的原始指针.从那时起,您的程序将永远无法释放该内存。
返回带有函数本地声明的自动存储的数组
When I run it, I do not have anything in newPath and it is empty.
struct path *resultPath[2];
声明一个指向struct path
的指针数组(其中两个)。 resultPath
的自动存储在其函数堆栈框架内声明为 copyPath
的本地。当copyPath
返回时,所有具有自动存储持续时间的局部变量都被销毁(释放函数栈帧内存以供重用)。 C11 Standard - §6.2.4 Storage durations of objects 明确解释了这一点
1) 对象的存储期限决定了它的生命周期。有四种存储持续时间:静态、线程、自动 和已分配。 7.22.3 中描述了分配的存储空间.
2) 对象的生命周期是保证为其预留存储空间的程序执行部分。一个对象存在,具有常量地址,33) 并在其整个生命周期内保留其最后存储的值。34) 如果在其生命周期之外引用对象,则行为未定义。当指针指向(或刚过去)的对象达到其生命周期的终点时,指针将变得不确定。
6) 对于这样一个没有可变长度数组类型的对象,它的生命周期从进入与其关联的 block 开始直到该 block 的执行以任何方式结束方式。
(强调我们的)
So, what is the best way to return these addresses and why I do not have it in newPath?
为了返回resultPath,需要为其动态分配存储空间,并返回指向它的指针。具有分配的存储持续时间的对象会在程序的生命周期内延长或直到它们被释放。
声明和分配一个能够存储两个指向struct path
指针的对象的最简单方法是声明一个pointer-to-pointer to 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
并且resultPath
的存储将在返回后继续存在,从而消除您对不再可用的内存的访问。然后,您可以在调用方中分别通过 newPath[0]
和 newPath[1]
访问 newHead
和 newTail
.
您还需要将 copyPath
的返回类型更改为 stuct path **
,例如
struct path **copyPath(struct path *head)
并更新调用者的类型。
关于c - 如何从 C 中的函数返回指针结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49526350/