分段错误 - 链表 (UNIX)

Segmentation Fault - linked lists (UNIX)

我想了解为什么我会收到分段错误。

我有一个链表 '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

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

如果我错了请纠正我:当我们尝试访问 "not exist"?

的内存时会发生分段错误

如有大神赐教,不胜感激

编辑:调试器信息:

 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;

My code is using multi-thread

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

因此,请考虑以下情况:

  • 您有两个线程,T1 和 T2。你有一个双节点链表。
  • T1 调用 你的代码 并看到 (ptr == head),然后继续前进。
  • 上下文切换!
  • T2 调用 你的代码 并看到 (ptr == head),然后继续前进。
  • T2套head = head->next
  • T2 检查 if (head != NULL),发现它 不是 NULL
  • 上下文切换!
  • T1 组 head = head->next

你认为 T1 分配给 head 什么?继续:

  • 上下文切换!
  • T2 分配 head->prev = NULL。它只是取消引用了由 T1 分配的 head。你认为会发生什么?

想象一下您的逻辑流程 所有 的这种上下文切换。你如何防范

这个问题的答案通常很好理解并且经常被问到(也经常被回答)。你应该可以从这里找到你想要的答案。