简体   繁体   English

链表的头在传递给函数时发生变化

[英]Head of a linked list changes when passed to a function

I've written a simple program including linked lists. 我编写了一个包含链接列表的简单程序。 When I try to display the linked list in the function it is created, it works alright; 当我尝试在创建的函数中显示链接列表时,它可以正常工作; however, when I return to main and try to display it, it does not work properly. 但是,当我返回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;
}

When debugging in print_list function called from main, "traverse->word" shows the correct value at first but it does not print it right and then it changes to some another value. 在从main调用的print_list函数中调试时,“ traverse-> word”首先显示正确的值,但不会正确打印,然后更改为另一个值。

The elements of ndArray are only valid within the scope of build_linked_list . ndArray的元素仅在build_linked_list范围内有效。 Once the program exists that function, any access to those elements yields undefined behavior. 一旦程序存在该功能,对这些元素的任何访问都会产生未定义的行为。 You are building your linked list with those elements. 您正在使用这些元素构建链接列表。 Instead, you need to allocate memory for the nodes of your linked list on the heap, or you need to move the ndArray variable to the file scope so that it exists for the lifetime of your main method. 相反,您需要为堆上链表的节点分配内存,或者需要将ndArray变量移至文件作用域,以便在main方法的整个生命周期中都存在该变量。

Inside build_linked_list you are declaring build_linked_list中声明

Node ndArray[N];

which is the Node you are filling within that function. 这是您要在该函数中填充的节点。 But when the execution ends the block of the build_linked_list function ndArray is deallocated therefore the pointer returned points to the memory previously allocated for ndArray but that now is no more occupied by that array. 但是,当执行结束时,将释放build_linked_list函数ndArray的块,因此返回的指针指向以前为ndArray分配的内存,但现在不再被该数组占用。

The usual implementation of linked lists is done using the heap and dynamic memory allocation. 链表的通常实现是使用堆和动态内存分配完成的。 When building your Node array you should write: 构建Node数组时,应编写:

Node* ndArray = new ndArray[N];

But at this point I higly suggest you to read about Garbage collectors and how to properly manage dynamic memory, because this is a whole new topic which has been discussed over and over here on StackOverflow. 但是在这一点上,我建议您阅读有关垃圾收集器以及如何正确管理动态内存的信息,因为这是一个全新的主题,已在StackOverflow上一再讨论。

For this answer I'll just anticipate to you that when allocating with new or new[] (for malloc and free see the C reference) you should as well delete with delete or delete[] respectively. 对于这个答案,我只是期望您在使用newnew[]分配时(对于mallocfree参见C参考),您也应该分别使用deletedelete[]进行delete In this case, when you are done with a linked list or ndArray you should write: 在这种情况下,当完成链表或ndArray ,应编写:

delete[] ndArray;

to free the memory. 释放内存。 Otherwise you'll have a memory leak. 否则您将发生内存泄漏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM