【问题标题】:Question on passing a pointer to a structure in C to a function?关于将指向 C 中结构的指针传递给函数的问题?
【发布时间】:2010-04-15 21:01:53
【问题描述】:

下面,我用 C 语言编写了一个原始单链表。函数“addEditNode”必须按值接收指针,我猜这意味着我们可以编辑指针的数据,但不能将其指向其他东西。如果我在“addEditNode”中使用 malloc 分配内存,当函数返回时,我可以看到 first->next 的内容吗?第二个问题是我必须先释放 -> 下一个还是我应该先释放?我在 Linux 上遇到分段错误。

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

typedef struct list_node list_node_t;

struct list_node
{ 
  int value;
  list_node_t *next;
};

void addEditNode(list_node_t *node)
{
   node->value = 10;
   node->next =  (list_node_t*) malloc(sizeof(list_node_t));
   node->next->value = 1;
   node->next->next = NULL; 
}

int main()
{
  list_node_t *first = (list_node_t*) malloc(sizeof(list_node_t));

  first->value = 1;
  first->next = NULL;

  addEditNode(first);

  free(first);

  return 0;
}

【问题讨论】:

  • 这是作业吗?如果是这样,它应该有作业标签。除此之外,上面的代码很好,除了你的免费。您需要释放所有已分配的内存。创建一个遍历列表的循环,随时释放节点。

标签: c pointers linked-list structure


【解决方案1】:

.. 表示我们可以编辑指针的数据但不能将其指向其他东西...

是的

如果我在addEditNode中使用malloc分配内存,当函数返回时,能看到first->next的内容吗?

是的。内存是在堆上分配的,所以你可以访问它。请注意,您仍然负责释放内存。

第二个问题是我必须先释放 -> 下一个还是只有首先我应该释放?

是的。您应该释放在堆上分配的所有内存。


虽然存在内存泄漏(first-&gt;next 不是 freed),但您可能不应该出现 seg-fault。

注意:

node->next =  (list_node_t*) malloc(sizeof(list_node_t));

显式转换不需要在 C 中 malloc 的情况下(在 C++ 中是必需的)。下面的就好了。

node->next = malloc(sizeof(list_node_t));

【讨论】:

    【解决方案2】:

    如果我在“addEditNode”中使用malloc分配内存,当函数返回时,我可以看到first-&gt;next的内容吗?

    是的,你可以在main看到它。

    第二个问题是我必须先释放 -> 下一个还是只有首先我应该释放?

    您还应该释放first-&gt;next,否则会出现内存泄漏。

    如果您在处理 first 后尝试取消引用它,可能会遇到分段错误。

    但是请注意,从链表中删除节点还需要重新排列指针以使链表保持有效状态。你应该为此编写一个单独的函数。

    【讨论】:

      【解决方案3】:

      首先,是的,当函数返回时,您可以“看到”first-&gt;next 的内容。 node-&gt;nextnode 指向的struct 中的一个值,它与first 指向同一个地方。当按值传递first 指针时,只复制指针本身,而不是它指向的整个结构。换句话说,main 中的*firstaddEditNode 中的*node 的数据完全相同(不是副本),只是每个函数都有一个不同 指针(一个叫做@ 987654330@ 和一个名为 node) 的名称指向该结构。

      第二,是的,你也必须释放node-&gt;next,否则你会泄漏。当您释放指向结构的指针时,它不会递归地释放属于该结构的指针。

      但是,我在该代码中看不到任何不正确或应该导致分段错误(泄漏不会导致分段错误)的内容。

      【讨论】:

        【解决方案4】:

        指针是一个整数,它指定内存中的地址。 “记忆”的细节在这里没有说明;只需知道指针包含一个数字,它是程序地址空间中的绝对字节。

        因此,当你传递一个指针时,你传递了一个地址。因此,通过编辑地址处的数据,您可以使您的更改在本地函数之外可见。所以是的,您将在 main() 中看到 addEditNode() 中所做的更改。

        当您动态分配内存时,您应该始终释放它。对堆所做的更改对程序来说是全局的。

        【讨论】:

          猜你喜欢
          • 2020-04-25
          • 1970-01-01
          • 2021-07-17
          • 1970-01-01
          • 2012-04-21
          • 1970-01-01
          • 1970-01-01
          • 2017-01-22
          • 1970-01-01
          相关资源
          最近更新 更多