0

我正在尝试在 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).
4

2 回答 2

2

您需要将此行添加到 AddClient

new->next = NULL;

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

于 2013-06-12T01:14:36.717 回答
0

有两个非常相似的问题:

  1. 添加到列表末尾时,您需要确保new->nextcontains 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");
    

由于这个未定义的成员,代码无法编译cliente = cliente -> proximo;......我想你打算将它修改为-> next. 请确保您将来测试您的测试用例。

于 2013-06-12T02:53:26.783 回答