在C中添加链接列表末尾或开头的节点

时间:2013-06-12 00:45:28

标签: c linked-list

我正在尝试使用Linux中的命名管道创建服务器/客户端程序。 每次客户端连接和验证时,服务器都会将其数据(pid和密码)存储在链表中。

问题是,在我存储第一个客户端的数据后,每当我尝试存储更多数据(客户端)时,程序“给出”分段错误

typedef struct client client, *pno;
struct client
{
    pid_t pid;
    char password[TAM_MAX];
    pno next;   
};

int verify_struct(pno cliente_t)
{
    if (cliente_t == NULL) //verifica se a lista está vazia
        return 1;
    else
        return 0;
}

    pno AddClient(pno cliente_t, pid_t pid, char password[TAM_MAX]) 
    {
        pno new, aux;
        new = malloc(sizeof(client)); //aloca espaço

        if(new == NULL) //verifica se alocou o espaço com sucesso
            {
                printf("Memory allocation error!\n");
                return cliente_t;
            }

        new->pid = pid;
        strncpy(new->password, password, TAM_MAX-1);

        if(verify_struct(cliente_t))
            {
                printf("Should be at start\n");
                cliente_t = new;
                printf("Added at start!\n");
            }
        else
            {
                //insert at end
                printf("Adding in the end!\n");
                aux = cliente_t;
                while(aux->next != NULL)
                    aux = aux->next;
                aux->next = new;
                printf("Added sucssefully!\n");
            }
        return cliente_t;
    }

bool isValidUser(pno cliente,  pid_t pid, char password[TAM_MAX])
{
    while(cliente != NULL)
        {
            if(cliente->pid == pid && strncmp(password, cliente->password, 100) == 0)
                {
                    return true;
                }
            cliente = cliente -> proximo;
        }
        return false;
}

    //progam itself :

int main(void)
{
    pno client=NULL;

    /* --code-- */

    while(1)
        {
                if(request.loggedIn == 0)
                    {
                        client=AddClient(client, request.pid, request.password);
                    }
                else
                    {
                        if(!isValidUser(cliente, perg.pid_cliente, perg.password))
                            abort();
                        //process commands
                    }
        }

}

输出:

1st Client -> Should be at start!
           -> Added at start!

2nd Client -> Adding in the end!
           -> segmentation fault (core dumped).

2 个答案:

答案 0 :(得分:2)

您需要将此行添加到AddClient

new->next = NULL;

否则new->next包含未初始化的内存。稍后当你检查aux->next != NULL(aux现在等于之前的那个)时,测试不会评估为true,因为未初始化的内存不会发生等于0.然后你试图找到另一个指向的节点未初始化内存中的值。它可能包含实际上不是合法内存地址的数据,因此存在分段错误。

答案 1 :(得分:0)

有两个非常相似的问题:

  1. 添加到列表末尾时,您需要确保new->next包含NULL,如上所述@morningstar。
  2. 添加到列表的开头时,您需要确保new->next包含cliente_t(在将其分配给new之前)。例如:

    printf("Should be at start\n");
    new->next = cliente_t;
    cliente_t = new;
    printf("Added at start!\n");
    
  3. 由于此cliente = cliente -> proximo;未定义成员,代码无法编译...我认为您打算将其修改为-> next。请确保您将来测试您的测试用例。