我是一个初学的C程序员,只是编写一个涉及队列操作的练习题,在调试时,我遇到了以下场景:
代码示例1:
int dequeue (struct queue_node * Q) {
struct queue_node * curr = Q->next;
if(!Q->next)
return -2;
else
{
int s = Q->next->v_no;
Q->next = curr->next;
free(curr);
return s;
}
}
Run Code Online (Sandbox Code Playgroud)
代码示例2(以稍微修改的方式编写的相同函数):
int dequeue (struct queue_node * Q) {
struct queue_node * curr = Q;
if(!curr->next)
return -2;
else
{
int s = curr->next->v_no;
Q->next = curr->next->next;
free(curr->next);
return s;
}
}
Run Code Online (Sandbox Code Playgroud)
预定义的数据结构如下:
struct queue_node {
int v_no;
struct queue_node * next;
};
void enqueue (struct queue_node * Q , int s) {
struct queue_node * curr = Q;
while (curr->next)
curr = curr->next;
curr->next = malloc(sizeof(struct queue_node));
if(!curr->next)
exit(10); //No specific reason for errno 10, just wanted to exit
curr->next->v_no = s;
curr->next->next = NULL;
}
Run Code Online (Sandbox Code Playgroud)
问题: 场景1中的代码允许程序成功执行并输出预期的答案但是根据我的理解,场景2中的代码也尝试实现相同的功能,但是会给出分段错误.有人可以指出,如果我的理解中缺少某些东西,或者我在代码本身出错了吗?
谢谢!
我们假设您的队列结构目前有三个元素:
{a} -> {b} -> {c} -> NULL
Run Code Online (Sandbox Code Playgroud)
与Q目前指向b.
让我们来看看你的每个函数会做什么.
/* Example 1 (working) */
int dequeue (struct queue_node * Q) {
struct queue_node * curr = Q->next; // curr = {c}
if(!Q->next) // c != NULL, so OK
return -2;
else
{
int s = Q->next->v_no; // s = c.v_no
Q->next = curr->next; // Q->next = NULL
free(curr); // free({c})
return s; // return c.v_no
}
}
Run Code Online (Sandbox Code Playgroud)
因此,示例1提供了指向Q节点的指针,将下一个节点出列并删除,然后返回它v_no.
/* Example 2 (segfaults) */
int dequeue (struct queue_node * Q) {
struct queue_node * curr = Q; // curr now points to the same element as q
if(!curr->next) // {b}->next == {c}, so OK
return -2;
else
{
int s = curr->next->v_no; // s = Q
Q->next = curr->next->next; // Q->next = NULL ({c}->next)
free(curr->next); // same as free (Q->next) == free(null)
return s;
}
}
Run Code Online (Sandbox Code Playgroud)
所以在第二个例子中,你释放一个空指针 - segfault!
| 归档时间: |
|
| 查看次数: |
128 次 |
| 最近记录: |