分段故障 - 链接列表(UNIX)

时间:2017-06-05 21:37:40

标签: c unix linked-list pthreads semaphore

我试图理解为什么我会收到细分错误。

我有一个链接列表' head'使用prev和next指针,我试图删除列表中的特定节点。特定节点的地址由' ptr'保存。 我附上了一张显示调试器的图片, 以下代码给出了分段错误: (我只展示了相关的内容)

void someFunc(char str[], int atmSN){


/*some code */ 

switch(ch){    /// ch is char

/* some code */

case 'Q':       
    if (ptr == head){                   // if ptr head of linked list
        head = head->next;
        if (head != NULL)
            head->prev = NULL;
    }
    else{
        ptr->prev->next = ptr->next;
        if (ptr->next != NULL)  // if ptr is not last
            ptr->next->prev = ptr->prev;
    }

    free(ptr);
break;

/*some code */ 

debugger

我的代码使用多线程,因此当前线程尝试删除时,可能是另一个线程正在写入特定节点。 在我的任务中,我也必须实现信号量,但这是否会给我们一个分段错误?

如果我错了,请纠正我:当我们尝试到达不存在的记忆时会发生分段错误"?

如果有人能够启发我,我将不胜感激。

编辑:调试器信息:

 Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff5ff9700 (LWP 3350)]
0x00000000004011cb in operation (str=0x7ffff5ff8e00 "Q 1111 1111", atmSN=3)
    at hw4.c:175
175                     ptr->prev->next = ptr->next;

1 个答案:

答案 0 :(得分:3)

  

我的代码使用的是多线程

多线程环境必须考虑锁定上下文,例如互斥锁或信号量。每当您同时运行多个执行线程(单核系统上的超线程,多核或抢占式多线程)时,请考虑执行线程可以在任何时候更改。你应该保护逻辑,以确保你不会自己甩脚。

因此,请考虑以下情况:

  • 你有两个线程,T1和T2。您有一个双节点链表。
  • T1调用您的代码并查看(ptr == head),并继续前进。
  • 上下文切换!
  • T2调用您的代码并查看(ptr == head),并继续前进。
  • T2设置head = head->next
  • T2检查if (head != NULL),看到非空
  • 上下文切换!
  • T1设置head = head->next

您认为T1如何分配给head?继续:

  • 上下文切换!
  • T2指定head->prev = NULL。它只是取消引用由head指定的T1。你觉得怎么样?

想象一下这种上下文切换所有的逻辑流程。你如何保护反对它?

这个问题的答案通常是很容易理解的,并经常被问到(并经常回答)。你应该能够从这里找到你想要的答案。