【问题标题】:Insert from back : Linked List从后面插入:链表
【发布时间】:2013-09-29 09:11:49
【问题描述】:

我从这个站点阅读了代码:http://www.codeproject.com/Articles/24684/How-to-create-Linked-list-using-C-C,但它给了我分段错误,我不太明白。

*我将它修改为我的结构

struct Node
{
    int type;
    char cmd[256];
    struct Node *next;
};

struct Node *head = NULL;

void insert(int val, char arr[])
{
    struct Node *temp1 = (struct Node*)malloc(sizeof(struct Node));
    struct Node *temp2 = (struct Node*)malloc(sizeof(struct Node));
    temp1 = head;
    while(temp1->next != NULL)
        temp1 = temp1->next;

    temp2->type = val;
    strcpy(temp2->cmd, arr);

    temp2->next = NULL;
    temp1->next = temp2;
}

这段代码有什么问题?

好的,这个问题解决了。谢谢Guyz'^'!您是否知道如何将字符 " (ASCII 34) 放入 printf 字符串中?(例如,如果我执行 printf("Print this "sentence""); 它会给我句子错误,cut I cast another set of “”在一个“”中。谢谢一堆。

【问题讨论】:

  • 哪一行导致了段错误?
  • 你不需要为temp1分配内存,否则你会发生内存泄漏。 struct Node *temp1 = head 很好。
  • 你能告诉我们struct Node的内容吗? (什么是cmd 成员)
  • 我只是看了链接页面的内容,真的很糟糕。不要使用它。
  • head 在哪里定义?你在任何地方初始化它吗?

标签: c insert linked-list


【解决方案1】:

首先,您未能在初始插入时设置头指针。这可以通过简单的头部检查来完成,但如果插入循环设置正确,则不需要它。其次,您正在泄漏内存。这不是 Java。覆盖一个保存动态分配地址的指针就像把内存扔出窗口一样好。

这是一种无需在插入代码中隐藏if (head == NULL) 特殊情况的方法。与流行的观点相反,如果您这样做,则不需要这种特殊情况:

void insert(int val, char arr[])
{
    struct Node **pp = &head;
    while (*pp)
        pp = &(*pp)->next;

    *pp = malloc(sizeof(**pp));
    (*pp)->next = NULL;
    (*pp)->type = val;
    strcpy((*pp)->cmd, arr);
}

只需确保在进行任何插入之前将 head 初始化为 NULL,通过查看更新后的帖子看起来您所做的是正确的。

最后,don't cast malloc() results in C programs.

【讨论】:

    【解决方案2】:

    试试这个,它将纠正内存泄漏并检查 head 是否有效。 如果仍然存在分段错误,则应运行调试器以准确了解发生了什么。

    void insert(int val, char arr[])
    {
        struct Node *temp2 = malloc(sizeof(struct Node));
        temp2->type = val;
        strcpy(temp2->cmd, arr);
        temp2->next = NULL;
    
        if (head == NULL) {
          //list is empty, head must points on the created node
          head = temp2;
        }
        else {
          struct Node *temp1 = head;
    
          while(temp1->next != NULL)
            temp1 = temp1->next;
    
          temp1->next = temp2;
       }
    }
    

    EDIT :现在,这个函数应该处理任何情况,即使head 为空。 (当列表为空时)

    【讨论】:

    • 好的,这个问题解决了。谢谢!您是否知道如何将字符 " (ASCII 34) 放入 printf 字符串中?(例如,如果我执行 printf("Print this "sentence""); 它会给我句子错误,cut I cast another set of “”在“”中。
    • @LarsChung 是的,只需添加转义字符:printf("Print this \"sentence\"");
    • nvm,我知道了,我可以做 %c 并将 ascii 值放在那里。无论如何,谢谢'^'
    • @LarsChung,如果你想添加任何 ascii 字符,不要使用 %c,你可以使用 \x(hex ascii value) 来做到这一点:printf("\x58\x59\x5A"); 将打印 XYZ
    【解决方案3】:

    您需要在运行第一次插入之前初始化head

    /* This should go in main or some init function, before the first insert */
    head = (struct Node *)malloc(sizeof(struct Node));
    head->next = NULL;
    

    【讨论】:

    • 当我从前面插入时,我把头留在我的问题中,它工作正常,有什么理由需要像这样从后面插入吗?
    • @LarsChung 因为while(temp1->next != NULL) 检查(它试图取消引用空指针)。我怀疑你的前端插件没有尝试访问head->next
    • 哦,是的,它有点固定,但我认为它仍然存在一些逻辑错误,我得到了一个额外的节点......我输入了 3 个字符串,但它给了我 4 个节点......
    • @LarsChung 那是因为您不需要设置初始节点。如果检查正确,您可以使用 NULL 的初始头指针来执行此操作。
    • @LarsChung,检查我的答案,它处理列表为空且不添加额外节点的情况。
    【解决方案4】:

    看到你引用的链接,还有一个测试文件http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=24684,它会告诉你为什么会出现这个错误,当从后面插入时,它会首先检查头部是否为空并为第一个元素。

    块引用

    1  #include<iostream>
      2  
      3  using namespace std;
      4  
      5  typedef struct node
      6  {
      7      int data;   // will store information
      8      node *next; // the reference to the next node
      9  };
     10  
     11  
     12  int main()
     13  {
     14      node *head = NULL;  //empty linked list
     15      int info = 0, node_number = 0,  counter = 0;
     16      char ch;
     17  
     18      do{
     19          cout<<"\n\n";
     20          cout<<"0.Quit\n";
     21          cout<<"1.Insert at first\n";
     22          cout<<"2.Traverse\n";
     23          cout<<"3.Insert at last\n";
     24          cout<<"4.Insert after specified number of node\n";
     25          cout<<"5.Delete at first node\n";
     26          cout<<"6.Delete at last node\n";
     27          cout<<"7.Delete specified number of node\n";
     28          cout<<"8.Sort nodes\n";
     29  
     30          cout<<"Enter your choice: ";
     31          cin>>ch;
     32  
     33      switch(ch)
     34      {
     35  
     36      case '0': break;
     37  
     38      case '1': ....
    
      .....  case '3':{
               **// check linked list is empty**
               if(head==NULL)
               {
                   cout<<"ENTER ANY NUMBER:";
                   cin>>info;                        // take input data
                   cout<<"Input data: "<<info;
    
                   node *temp;                     // create a temporary node
                   temp = (node*)malloc(sizeof(node)); // allocate space for node
                   temp->data = info;               // store data(first field)
                   temp->next = NULL;               // second field will be null
                   head = temp;                    // transfer the address of 'temp' to 'head'
                   counter++;
               }
    
               else
               {
                   cout<<"ENTER ANY NUMBER:";
                   cin>>info;                        // take input data
                   cout<<"Input data: "<<info;
                   node *temp1;                        // create a temporary node
                   temp1=(node*)malloc(sizeof(node));  // allocate space for node
                   temp1 = head;                   // transfer the address of 'head' to 'temp'
                   while(temp1->next!=NULL)         // go to the last node
                       temp1 = temp1->next;         //tranfer the address of 'temp->next' to 'temp'
    
                   node *temp;                 // create a temporary node
                   temp = (node*)malloc(sizeof(node));// allocate space for node
                   temp->data = info;               // store data(first field)
                   temp->next = NULL;               // second field will be null(last node)
                   temp1->next = temp;              // 'temp' node will be the last node
                   break;
                }
       }
    

    【讨论】:

    • 操作列表类似,我只看到输入/输出函数调用的不同,很容易转换。
    • 你最好编写你的函数来处理两种情况:AddToHead() 和 AddToBack(),而不仅仅是 insert()
    猜你喜欢
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-31
    • 2017-08-27
    • 2013-02-28
    • 2016-06-04
    相关资源
    最近更新 更多