C中的链接列表丢失了头部信息

时间:2011-02-01 05:35:15

标签: c linked-list

我在C中实现了一个基本链表,作为开发简单shell的项目的一部分 - 它通过维护shell在后台运行的pid列表来支持进程的后台处理。代码如下。使用queue_process(some_pid)插入第一次工作正常,但随后链表的行为就好像列表中从未有任何节点(即调试函数始终打印“无现有进程”)。我已经检查过这个文件以及调用这些函数的文件,以便将头指针重置为无效。我在链表逻辑中遗漏了什么吗?

对queue_process编辑的调用:发生在shell启动的子进程中,看起来像这样/编辑:queue_process(getpid())

谢谢!

    void queue_process(pid_t pid_to_insert)
{
    pmesg(2, "In queue_process.\n");
    if (head == NULL)
    {
        pmesg(3, "No existing processes.\n");
        head = malloc(sizeof(struct xssh_process));
        head->pid = pid_to_insert;
        head->next = NULL;
    }
    else
    {
        pmesg(3, "There are existing processes.\n");
        struct xssh_process *new_process = malloc(sizeof(struct xssh_process));
        new_process->next= head;
        head = new_process;
    }
    print_processes();
}

void print_processes()
{
    pmesg(2, "In print_processes.\n");
    struct xssh_process *at_node = head;
    if (head == NULL) { pmesg(2, "There are currently no background processes.\n"); return; }
    pmesg(2, "Process IDs from head (most recently executed) to tail: %i -> ", at_node->pid);
    while (at_node != NULL)
    {
        pmesg(2, "%i ->", at_node->pid);
        at_node = at_node->next;
    }
    pmesg(3, "Head's pid in print is %i.\n", head->pid);
}

4 个答案:

答案 0 :(得分:3)

这对你遇到的错误毫无帮助,但你的代码让我觉得过于复杂:

pmesg(2, "In queue_process.\n");
if (head == NULL)
{
    pmesg(3, "No existing processes.\n");
    head = malloc(sizeof(struct xssh_process));
    head->pid = pid_to_insert;
    head->next = NULL;
    tail = malloc(sizeof(struct xssh_process));
    tail = head;
}
else
{
    pmesg(3, "There are existing processes.\n");
    struct xssh_process *new_process = malloc(sizeof(struct xssh_process));
    new_process->next= head;
    head = new_process;
}

这可以简化很多。由于您无论如何都要插入列表的头部,因此对于空列表不需要单独的逻辑:

void queue_process(pid_t pid_to_insert) { 
   struct xssh_process *new_process = malloc(sizeof(*new_process));
   new_process->pid = pid_to_insert;
   new_process->next = head;
   head = new_process;
}

同样,print_processes可以减少一点:

void print_processes() { 
    struct xssh_process *p;
    for (p=head; p!=NULL; p=p->next)
        printf("%d\n", p->pid);
}
OTOH,一个链表让我感觉不错 - 鉴于指针至少和PID一样大,至少有50%的内存是指针的开销。

答案 1 :(得分:1)

当变量的值神秘地改变时,通常是因为你写的超出了另一个变量的边界,恰好在内存中相邻。

尝试在head上的调试器中设置一个观察点,只要该变量发生变化,它就会进入调试器。这可以让您快速跟踪问题。在gdb中,命令为watch head

答案 2 :(得分:1)

根据您提供的额外信息:

  

对queue_process的调用发生在   子进程由shell启动   看起来像这样:   queue_process(getpid())

您正尝试添加到子进程中的链接列表(由fork()创建),然后检查父级中的链接列表。

这不起作用 - fork()创建一个完整的独立的副本。除了明确标记为共享的内存之外,在fork()之后对变量进行的修改对每个进程都是私有的。父母不会看到孩子做出的修改,孩子也不会看到父母做出的修改。

您应该让父母致电queue_process(child_pid),其中child_pidfork()的返回值。

答案 3 :(得分:0)

试试这个:

void queue_process(pid_t pid_to_insert)
{
    pmesg(2, "In queue_process.\n");
    if (head == NULL)
    {
        pmesg(3, "No existing processes.\n");
        head = malloc(sizeof(struct xssh_process));
        head->pid = pid_to_insert;
        head->next = NULL;
        // This malloc is not required
        // tail = malloc(sizeof(struct xssh_process));
        tail = head;
    }
    else
    {
        pmesg(3, "There are existing processes.\n");
        struct xssh_process *new_process = malloc(sizeof(struct xssh_process));
        new_process->next= head;
        head = new_process;
    }
    print_processes();
}

void print_processes()
{
    pmesg(2, "In print_processes.\n");
    if (head == NULL) { pmesg(2, "There are currently no background processes.\n"); return; }
    struct xssh_process *at_node = head;

    // While at_node != null
    do
    {
        pmesg(2, "%i ->", at_node->pid);
        at_node = at_node->next;
    }
    while (at_node != null);
    pmesg(3, "Head's pid in print is %i.\n", head->pid);
}