结构体对象初始化:堆/栈分配差异及运行时错误解析
你的原代码逻辑是通顺的:用new ListNode(0)在堆上分配哑节点,借助它处理链表头节点的删除场景,最后用delete释放该哑节点,完全符合C++内存管理规则,因此运行正常。
第一个错误:ListNode* dummy_head(0); 引发空指针访问
你误以为这是栈分配的写法,但实际上这是指针的初始化语法:ListNode* dummy_head(0); 等价于 ListNode* dummy_head = nullptr;(0可隐式转换为空指针)。此时dummy_head是空指针,后续执行dummy_head->next = head;时,属于对空指针进行成员访问,直接触发空指针运行时错误,也就是你看到的:
runtime error: member access within null pointer of type 'ListNode'
(solution.cpp) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior
prog_joined.cpp:25:21
如果想在栈上创建哑节点,正确写法是ListNode dummy_head(0);(不带指针星号),但这会引出你遇到的第二个问题。
第二个错误:对栈对象指针执行delete导致内存非法操作
你尝试的写法:
ListNode dummy_head_object(0); ListNode* dummy_head = &dummy_head_object;
这里dummy_head_object是在栈内存上创建的局部对象,栈内存的生命周期由编译器自动管理:函数执行结束时,栈对象会被自动销毁。而delete仅用于释放堆内存(通过new分配的内存),对栈内存地址执行delete属于非法操作,因此触发内存检测工具报错:
22ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: in thread T0 #3 0x7f2d42339082
(/lib/x86_64-linux-gnu/libc.so.6+0x24082) Address 0x7ffd4fb4e400 is
located in stack of thread T0 at offset 32 in frame This frame has 1
object(s): [32, 48) 'dummy_head_object' <== Memory access at offset 32
is inside this variable
如果想用栈上的哑节点,只需删除代码中delete dummy_head;这一行即可,栈对象会自动销毁,无需手动释放。
内容的提问来源于stack exchange,提问作者Skylar

