C中的链表丢失头信息
我已经用 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);
}
I've implemented a basic linked list in C as part of a project to develop a simple shell - it supports backgrounding of processes by maintaining a list of the pids that the shell has run in the background. Code is below. Inserting with queue_process(some_pid)
works fine the first time, but subsequent times the linked list acts as if there are never any nodes in the list (i.e. "No existing processes" is always printed by the debug function). I've checked this file and the file that calls these functions for anything that would reset the head pointer to no avail. Am I missing something in my linked list logic?
The call to queue_process EDIT: happens in the child process started by the shell and looks like this /EDIT: queue_process(getpid())
Thanks!
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这对您遇到的错误没有帮助,但您的代码让我觉得过于复杂:
这可以简化很多。因为无论如何你都是在列表的头部插入的,所以你不需要为空列表单独的逻辑:
同样, print_processes 可以稍微修剪一下:
OTOH,链表让我觉得这是一个糟糕的选择 - 考虑到这一点指针至少与 PID 一样大,至少 50% 的内存是指针的开销。
It's no help with the bug you've encountered, but your code strikes me as excessively complex:
This can be simplified quite a bit. Since you're inserting at the head of the list anyway, you don't need separate logic for an empty list:
Likewise, print_processes can be trimmed down a bit:
OTOH, a linked list strikes me as a poor choice -- given that a pointer is at least as large as a PID, at least 50% of your memory is overhead for the pointers.
根据您提供的额外信息:
您正在尝试添加到子进程(由
fork()
创建)中的链表,然后检查父进程中的该链表。这是行不通的 -
fork()
创建一个完整的、独立的进程副本。除了显式标记为共享的内存之外,在fork()
之后对变量进行的修改对于每个进程都是私有的。父级不会看到子级所做的修改,子级也不会看到父级所做的修改。您应该让父进程调用
queue_process(child_pid)
,其中child_pid
是fork()
的返回值。Based on your extra information supplied:
You are trying to add to the linked list in a child process (created by
fork()
) and then examine that linked list in the parent.This won't work -
fork()
creates a complete, independent copy of the process. Except for memory that is explicitly marked as shared, modications to variables made after thefork()
are private to each process. The parent won't see modifications made by the child, and the child won't see modifications made by the parent.You should have the parent call
queue_process(child_pid)
, wherechild_pid
is the return value offork()
.当一个变量的值神秘地发生变化时,通常是因为您写入的内容超出了另一个变量的范围,而该变量恰好在内存中相邻。
尝试在调试器的
head
上设置一个观察点,只要该变量发生变化,该观察点就会中断到调试器。这应该可以让您快速找到问题。在gdb
中,命令为watch head
。When a variable's value mysteriously changes, it's often because you're writing beyond the bounds of another variable, that happens to be adjacent in memory.
Try setting a watch point in your debugger on
head
, which will break into the debugger whenever that variable changes. This should let you track the issue down quite quickly. Ingdb
, the command would bewatch head
.试试这个:
Try this: