c - 段错误 - 链表 (UNIX)

标签 c unix linked-list pthreads semaphore

我试图理解为什么我收到段错误。

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

最佳答案

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。你认为会发生什么?

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

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

关于c - 段错误 - 链表 (UNIX),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44378083/

相关文章:

c++ - UNIX/OSX 版本的 semtimedop

c - C 中的链表

c - 我不明白为什么每次调用此函数后头节点都会不断变化

c - 如何搜索字符串并替换文本文件中的字符串?

c - 用于字母数字的 flex RE 也会打印 #$@

c - 如何在 C 中读取制表符分隔整数的文本文件?

linux - 语法错误 : end of file unexpected (expecting "done")

c - 当 argv*[] 是一个字符串时,如何通过 c 中的命令行传递数组?

shell - 从shell脚本中的每一行中删除字符

java - 根据用户输入从LinkedList获取值