C-分割故障 - 链接列表(UNIX)



我试图理解为什么要收到分割故障。

我有一个链接的列表"头",带有预列和下一个指针,我正在尝试删除列表中的特定节点。特定节点的地址由" 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 */ 

调试器

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

如果我错了,请纠正我:当我们尝试达到"不存在"的内存时,分割故障会发生?

如果有人能启发我,我会很感激。

编辑:调试器信息:

 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;

我的代码正在使用多线程

多线程环境必须使您考虑锁定上下文,例如静音或信号量。每当您同时具有多个执行线程(超线程,多核或单核系统上的预先避免的多线程(时,请考虑执行的 thread of Execution 可以在任何情况下更改力矩 guard 的逻辑取决于您,以确保您不会吹自己的脚。

因此,考虑以下方案:

  • 您有两个线程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。您认为发生了什么?

想象一下逻辑流的所有 all 的上下文切换。您如何守卫反对它?

这个问题的答案通常被妥善理解,并且经常被问到(并且经常回答(。您应该能够从这里找到您寻找的答案。

最新更新