C 如何为函数中的结构正确分配内存以返回其值供以后使用,以及如何将结构强制转换为指针?
我目前正在自学C,以便掌握一个大学项目。在该项目中,我们有几个签名,这些签名是为了解决我们的任务而需要实现的。经过几个小时的努力取得了一些进展,我必须承认我对函数的返回类型完全感到困惑。我将向您展示一些代码: 这是一种表示以32为基数的幂的数字的结构C 如何为函数中的结构正确分配内存以返回其值供以后使用,以及如何将结构强制转换为指针?,c,pointers,memory,struct,C,Pointers,Memory,Struct,我目前正在自学C,以便掌握一个大学项目。在该项目中,我们有几个签名,这些签名是为了解决我们的任务而需要实现的。经过几个小时的努力取得了一些进展,我必须承认我对函数的返回类型完全感到困惑。我将向您展示一些代码: 这是一种表示以32为基数的幂的数字的结构 #include <stdio.h> #include <stdlib.h> typedef unsigned int uint32; typedef struct { int n; uint32* words;
#include <stdio.h>
#include <stdlib.h>
typedef unsigned int uint32;
typedef struct
{
int n;
uint32* words;
}
foo;
如您所见,该函数将指向结构的两个指针作为参数,并返回结构的值,而不是指向结构的指针。这意味着我必须在本地创建一个foo实例并返回它
foo add(foo* a, foo* b)
{
foo result = {1, malloc(sizeof(uint32))};
// do something with result
return result;
}
1)这次尝试有什么错误吗?在我的生产代码中,我在访问返回的结构的值时遇到了问题:在返回结构后,它们似乎发生了变化。不幸的是,我无法在一个更简单的应用程序中重现这种行为,这让我更加担心我做的都是错的。我还尝试使用malloc为变量result分配内存,但这似乎只有在创建指向foo的指针时才起作用,因为我无法返回指针,这似乎是没有选项的
2)
我正在寻找一种将返回类型(可能不是正确的术语)转换回指针的方法。
让我们假设我有以下代码:
foo* bar1 = malloc(sizeof(foo));
bar1->n = 1;
bar1->words = malloc(bar1->n * sizeof(uint32));
bar1->words[0] = 4294967295;
foo* bar2 = malloc(sizeof(foo));
bar2->n = 1;
bar2->words = malloc(bar2->n * sizeof(uint32));
bar2->words[0] = 21;
foo bar3 = add(bar1, bar2);
很好。我现在如何使用bar3的值再次调用add函数。像这样:
foo bar4 = add(bar1, bar3);
After还尝试了创建foo*和分配值的各种尝试,但都失败了,我决定发布这个问题,以获得一些好的答案,帮助我更好地理解C。您正在查找运算符的地址,&&foo3将返回一个指向foo3的指针。更新我收回先前的解释。我通过valgrind运行了您的代码,事实上,您不会产生任何泄漏或错误的内存访问。按照您的方式,结构是按值返回的,因此在返回时会将其复制到新结构中。完成后,您唯一需要做的就是
free()
单词指针
你奇怪的结果可能是你正在做的事情的结果,这里没有显示
您需要返回指向foo的指针:
foo* add (foo* a, foo* n) {
foo result* = malloc(...);
/* do some addition */
return result;
}
不要忘记free()
通过这种方式获得的foo
结构
到unDrTrand您的方法不起作用的原因,考虑在<代码> Advices()/代码>作用域中声明的变量的生存期:
add()
foo
结构,并将其分配给变量result
add()
返回并释放该范围内变量的内存add()
之外,调用方接收存储在内存中标记为未使用的位置的结构add()
result
中add()
返回result
的值(表示内存中地址的整数)add()
之外,result
指向的位置仍然是堆上的分配位置,返回的指针可以安全地取消引用free(result)
,该位置被标记为未使用 printf("[bar3] n %d words %d\n", bar3.n, *(bar3.words));
2) 要将bar3
再次传递到函数add
。您需要传递bar3的mem地址,该地址可通过操作员和访问:
foo bar4 = add(bar1, &bar3);
或
如果这样做,则可以保留函数的定义而不返回指针。Edited:我不能使用返回foo*的函数签名。我要还福。我还尝试了foo result=malloc(sizeof(foo));但这只会给我一个编译错误,说明我使用了无效的初始值设定项。我更新了我的答案,你需要执行foo*result=malloc(…)
,我输入了一个错误。您的函数必须返回一个foo*
,才能按照您描述的方式工作。谢谢您的回答。好的,你证明了我对堆栈/堆上内存管理的变量作用域的理解是正确的。让我困惑的是,这个函数的签名必须与我在问题中发布的签名匹配。(由大学给出)我必须归还foo,我不能归还foo*。根据你的帖子和我对内存分配的理解,我似乎不知道该怎么做。为什么你必须返回foo
?为什么签名是固定的?也许如果你发布真实的代码,问题就显而易见了。另一种可能性是,您可以修改传入的foo
之一,而不是返回foo
。因为该方法的签名在大学提供的需求规范中给出。(我知道这个任务与现实世界中的任何应用程序都相去甚远,但不幸的是,我必须以这种方式编写代码才能通过笔试。)@citronas:我要说得清楚一点——在示例add()
函数中,返回struct
的方式没有任何问题。在您的完整程序中,问题很可能是您分配s的单词成员的方式
foo bar4 = add(bar1, &bar3);
foo bar3_p = &bar3;
foo bar4 = add(bar1, bar3_p);