我试图理解为什么我收到段错误。
我有一个带有上一个和下一个指针的链表“头”,我正在尝试删除列表中的特定节点。特定节点的地址由“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;
最佳答案
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/