【发布时间】:2019-11-21 16:02:58
【问题描述】:
在尝试在 C 中实现双向链表时,我注意到以下 sn-p 会在 macOS 10.11 El Capitan 上引发分段错误。但是,在 Linux 或 Haiku 中进行测试时,它会运行良好,并产生预期的结果。
#include <stdio.h>
#include <stdlib.h>
typedef struct node_structure {
int data;
struct node_structure *prev;
struct node_structure *next;
} *node;
node createNode(int value) {
node newNode = (node) malloc(sizeof(node));
if (newNode != NULL) {
newNode->data = value;
newNode->prev = NULL;
newNode->next = NULL;
}
return newNode;
}
void displayLinkedList(node linked_list) {
node cursor = linked_list;
while (cursor != NULL) {
printf("DATA: %d \tTHIS:%p \tPREV:%p \tNEXT:%p\n", cursor->data, (void*)cursor, (void *)cursor->prev, (void *)cursor->next);
cursor=cursor->next;
}
}
int insertAtHead(node *head, int value) {
node newHead = createNode(value);
if(newHead != NULL) {
(*head)->prev = newHead;
newHead->next = *head;
*head = newHead;
return 0;
}
else return 1;
}
int main() {
printf("\nCreating a single element linked list.\n");
node head = createNode(10);
displayLinkedList(head);
printf("\nInserting 10 elements at head.\n");
for(int i = 0; i < 10; i++) {
insertAtHead(&head, 8);
}
displayLinkedList(head);
return 0;
}
这是控制台输出:
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ gcc -Wall -pedantic 04_doubly_linked_lists__debugging.c
$ ./a.out
Creating a single element linked list.
DATA: 10 THIS:0x7fd19a403390 PREV:0x0 NEXT:0x0
Inserting 10 elements at head.
DATA: 8 THIS:0x7fd19a403430 PREV:0x0 NEXT:0x7fd19a403420
DATA: 8 THIS:0x7fd19a403420 PREV:0x7fd19a403430 NEXT:0x7fd100000008
Segmentation fault: 11
如您所见,在崩溃前的最后一次迭代中,next 指针似乎被结构的data 字段中的值覆盖(在此示例中,值为 8 的整数) .
让这件事特别奇怪的是,相同的代码在其他操作系统中运行时没有任何问题,完成了 10 个元素的插入循环,并将所有元素和各自的内存地址正确显示到屏幕上。
我在这里做错了吗?
【问题讨论】:
-
Windows 7 上的 MSVC 也会崩溃。不安全行为的典型症状是 a) 在这里有效,b) 在那里无效。
-
在
typedefs 中隐藏指针会混淆代码,使其难以理解。 -
错误
malloc(sizeof(node))是其结果之一。 -
参见Is it a good idea to typedef pointers — TL;DR 是“否”。
标签: c macos data-structures segmentation-fault doubly-linked-list