【问题标题】:Head of a linked list changes when passed to a function传递给函数时,链表的头部发生变化
【发布时间】:2013-03-24 21:08:45
【问题描述】:

我编写了一个包含链表的简单程序。当我尝试在它创建的函数中显示链表时,它工作正常;但是,当我返回 main 并尝试显示它时,它无法正常工作。

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

#define LEN 20 
struct Node {
char word[LEN];
int count;
Node * next;
};

Node* build_linked_list (char array[][LEN], int N);
Node* make_ordered_copy (Node * head);
void print_list(Node * head);


int main()
{
#define NUMBER 10
char array[NUMBER][LEN]; // array which the words will be recorded
int N=6;
for(int a=0; a<N; ++a) strcpy(array[a], "test");
print_list(build_linked_list(array, N));
getchar();
return 0;
}

Node* build_linked_list (char array[][LEN], int N)
{
  Node ndArray[N];
  Node *head, *newnode;

  head = &ndArray[0];
  strcpy(head->word, array[0]); // writing the first element to the head
  head->count = 0;
  head->next = NULL;

  for(int a=1; a<N; ++a) // writing the elements in a linked list 
  {
    newnode = &ndArray[a];
    strcpy(newnode->word, array[a]); 
    newnode->count = 0;
    newnode->next = head; // first location now becomes second location
    head = newnode;
  }  

  print_list(head);
  printf("Previous values were shown in build_linked_list\n");

  return head;
}

void print_list(Node* head)
{
 Node* traverse;
 traverse = head;

 while(traverse) // while traverse is not NULL
 {
   printf("\"%s\" with the frequency of %d\n", traverse->word, traverse->count);
   traverse = traverse->next;
 }


 return;
}

在从 main 调用的 print_list 函数中调试时,“traverse->word”首先显示正确的值,但它没有正确打印它,然后它会更改为另一个值。

【问题讨论】:

    标签: c linked-list pass-by-reference


    【解决方案1】:

    ndArray 的元素只在build_linked_list 的范围内有效。一旦程序存在该函数,对这些元素的任何访问都会产生未定义的行为。您正在使用这些元素构建您的链表。相反,您需要在堆上为链表的节点分配内存,或者您需要将 ndArray 变量移动到文件范围,以便它在您的 main 方法的生命周期内存在。

    【讨论】:

    • 好的,非常感谢。当我第一次写那部分时,我已经考虑过这一点,但不知何故,我说服自己会没事的:D。现在它工作正常,再次感谢。
    【解决方案2】:

    build_linked_list 中你声明了

    Node ndArray[N];
    

    这是您在该函数中填充的节点。但是当执行结束时,build_linked_list 函数块ndArray 被释放,因此返回的指针指向先前为ndArray 分配的内存,但现在该数组不再占用该内存。

    链表的通常实现是使用堆和动态内存分配来完成的。 在构建 Node 数组时,您应该编写:

    Node* ndArray = new ndArray[N];
    

    但在这一点上,我强烈建议您阅读有关垃圾收集器以及如何正确管理动态内存的信息,因为这是一个全新的话题,已经在 StackOverflow 上反复讨论过。

    对于这个答案,我只是希望您在使用 newnew[] 进行分配时(对于 mallocfree,请参阅 C 参考),您还应该使用 delete 或 @987654332 删除@ 分别。在这种情况下,当你完成一个链表或ndArray 你应该写:

    delete[] ndArray;
    

    释放内存。否则你会有内存泄漏。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-20
      • 2017-04-01
      • 2015-09-21
      • 2015-12-14
      • 1970-01-01
      • 2019-10-29
      • 1970-01-01
      相关资源
      最近更新 更多