加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何为函数中的结构正确分配内存以返回其值以供以后使用以及如何

发布时间:2020-12-16 09:29:17 所属栏目:百科 来源:网络整理
导读:我目前正在自学C以掌握大学项目.在该项目中,我们有几个签名,因为我们需要实施以解决我们的任务.经过几个小时试图取得一些进展,我必须承认我对函数的返回类型完全感到困惑.我会告诉你一些代码: 这是用于表示基础32的幂的数字的结构. #include stdio.h#includ
我目前正在自学C以掌握大学项目.在该项目中,我们有几个签名,因为我们需要实施以解决我们的任务.经过几个小时试图取得一些进展,我必须承认我对函数的返回类型完全感到困惑.我会告诉你一些代码:

这是用于表示基础32的幂的数字的结构.

#include <stdio.h>
#include <stdlib.h>

typedef unsigned int uint32;
typedef struct 
{
  int n;
  uint32* words;
}
foo;

我们需要实现一些具有以下签名的函数:

foo add(foo* a,foo* b);

你可以看到,该函数将结构作为参数的两个指针,并返回结构的值,而不是指向它的指针.这意味着我必须在本地创建一个foo实例并将其返回.

foo add(foo* a,foo* b)
{
  foo result = {1,malloc(sizeof(uint32))};
  // do something with result
  return result;
}

1)这次尝试有什么不对吗?在我的生产代码中,我遇到了访问返回结构的值的问题:它们似乎在返回结构后发生了变化.不幸的是,我无法在一个更简单的应用程序中重现这种行为,这让我更加担心我做错了.我也尝试使用malloc为变量结果分配内存,但是如果我创建一个指向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);

之后还尝试了创建foo *并尝试分配值的各种尝试,但它们都失败了,我决定发布这个问题以获得一些很好的答案,这有助于我更多地理解C语言.

解决方法

更新我撤回了我之前的解释.我通过valgrind运行你的代码,实际上你不会产生任何泄漏或不正确的内存访问.你拥有它的方式,结构由值返回,因此它在返回时被复制到一个新的结构中.当你完成时,你唯一需要做的就是free()单词指针.

你的奇怪结果可能是你正在做的事情的结果,这里没有显示.

你需要返回一个指向foo的指针:

foo* add (foo* a,foo* n) {
  foo result* = malloc(...);

  /* do some addition */

  return result;
}

不要忘记释放()以这种方式获得的foo结构.

为了解决您的方式不起作用的原因,请考虑在add()范围内声明的变量的生命周期:

>输入了add().
>创建一个新的foo结构并将其分配给变量result.
>函数add()返回,并释放该范围内变量的内存.
>在add()之外,调用者接收存储在内存中标记为未使用的位置的结构.
>尝试访问该结构会产生未定义的结果,因为它所在的内存可以分配给其他数据.

考虑我提出的解决方案的流程:

>输入了add().
>在堆上分配新内存,并将该内存的地址存储在result中.
>函数add()返回result的值(一个表示内存中地址的整数).
>在add()之外,result指向的位置仍然是堆上的已分配位置,并且可以安全地取消引用返回的指针.
>完成该位置的结构后,调用free(result)并将该位置标记为未使用.

希望有所帮助!有关详细信息,您应该调查内存堆是什么以及分配如何工作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读