我的链接列表中的分配不起作用

时间:2019-07-31 12:14:28

标签: c list insert singly-linked-list

我正在尝试实现一个链表,该链表仅在列表中不存在项时才插入该项。如果该项目存在,则ent_exists返回指向该项目的指针。

typedef struct nodo_ent{
  struct nodo_ent *next;
  char *ent;
}nodo_ent;

nodo_ent *head;
nodo_ent *tail;
head = NULL;
tail = NULL;

nodo_ent *ent_exists(char *ent)
{
  if (head == NULL)
 {
   return NULL;
 }
 else
 {
   nodo_ent *cursor;
   cursor = head;
   while (cursor != tail)
   {
     if (strcmp(cursor->ent, ent) == 0);
     {
       return cursor;
     }
     cursor = cursor->next;
   }
   if (strcmp(tail->ent, ent) == 0);
   {
     return tail;
   }
   return NULL;
 }
}

void addent(char *ent)
{
  if (ent_exists(ent) != NULL)
  {
    return;
  }
  else
  {
    nodo_ent nodo = {NULL, ent};
    nodo_ent *ptr;
    ptr = (nodo_ent*)malloc(sizeof(nodo_ent));
    ptr = &nodo;
    if (head == NULL)
    {
      head = ptr;
      tail = ptr;
    }
    else
    {
      tail->next = ptr;
      tail = ptr;
    }
    return;
  }
}


在第一次调用“ addent”之后,“ head”和“ tail”都指向已添加节点的地址,但是当我第二次调用它并尝试访问tail-> ent时(在ent_exists中), valgrind说它还没有初始化

2 个答案:

答案 0 :(得分:2)

正如风向标指出的那样,

nodo_ent nodo = {NULL, ent};
nodo_ent *ptr;
ptr = (nodo_ent*)malloc(sizeof(nodo_ent));
ptr = &nodo;

此序列分配内存,然后使用局部变量nodo的地址覆盖指向此分配内存的指针。

然后您使用此局部变量,但是当函数返回时,该局部变量不再存在并且您的列表已损坏。

所有内容都在那里,只需使用:

nodo_ent *ptr;
ptr = malloc(sizeof(nodo_ent));

(并且不要转换malloc的结果。malloc返回的指向void的指针与任何指针都兼容。)

答案 1 :(得分:0)

对于初学者,如果此代码段为

nodo_ent *head;
nodo_ent *tail;
head = NULL;
tail = NULL;

位于全局名称空间中,因此代码将无法编译。

函数ent_exists太复杂了。

它可以更简单地实现。

nodo_ent * ent_exists( const char *ent )
{
    nodo_ent *cursor = head;

    while ( cursor != NULL && strcmp( cursor->ent, ent ) != 0 )
    {
        cursor = cursor->next;
    }

    return cursor;  
}

函数addent的返回类型应为int,以报告是否成功插入新节点。

此代码段

nodo_ent nodo = {NULL, ent};
nodo_ent *ptr;
ptr = (nodo_ent*)malloc(sizeof(nodo_ent));
ptr = &nodo;

没有意义,而且存在内存泄漏。

您必须复制作为参数传递的字符串。否则,该程序通常将具有未定义的行为。

这里是一个演示程序,显示了如何定义功能。

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

typedef struct nodo_ent{
  struct nodo_ent *next;
  char *ent;
}nodo_ent;

nodo_ent *head = NULL;
nodo_ent *tail = NULL;

nodo_ent * ent_exists( const char *ent )
{
    nodo_ent *cursor = head;

    while ( cursor != NULL && strcmp( cursor->ent, ent ) != 0 )
    {
        cursor = cursor->next;
    }

    return cursor;  
}

int addent( const char *ent )
{
    nodo_ent *target_nodo = ent_exists( ent );

    int success = target_nodo == NULL;

    if ( success )
    {
        target_nodo = malloc( sizeof( nodo_ent ) );
        success = target_nodo != NULL;
    }

    if ( success )
    {
        char *s = malloc( strlen( ent ) + 1 );

        success = s != NULL;

        if ( success )
        {
            strcpy( s, ent );
            target_nodo->ent = s;
            target_nodo->next = NULL;
        }           
        else 
        {
            free( target_nodo );
        }           
    }

    if ( success )
    {
        if ( head == NULL )
        {
            head = tail = target_nodo;
        }
        else
        {
            tail = tail->next = target_nodo;
        }
    }       

    return success;
}

void output()
{
    for ( nodo_ent *cursor = head; cursor != NULL; cursor = cursor->next )
    {
        printf( "%s ", cursor->ent );
    }
}

int main(void) 
{
    const char *ent;

    ent = "Hello";
    addent( ent );

    ent = "Jack";
    addent( ent );

    output();

    return 0;
}

其输出为

Hello Jack