动态链表触发Segmentation fault:11故障,如何正确实现尾插节点?
Hey there! Let's figure out why you're hitting that segmentation fault and fix your linked list implementation properly.
The Root Cause
The main issue here is that in your newSuper() function, after allocating memory for struct Super, you never initialize the Sub pointer. That means self->Sub is a wild pointer—it holds a random garbage value, not the NULL you expect. When addSub tries to access head->next using this wild pointer, it's trying to read invalid memory, which triggers the segmentation fault.
Fixes & Improved Implementation
Let's go through the key fixes and proper way to implement this:
Initialize the Linked List Head
Always set your initial list head toNULLwhen creating a newSuperinstance. This tells your code the list is empty to start with.Properly Add Nodes to the End
- For empty lists, just set the head to the new node.
- For non-empty lists, traverse until you find the last node (where
nextisNULL), then attach the new node there. - Don't forget to initialize the new node's
nextpointer toNULL—otherwise, you'll end up with another wild pointer in your list.
Add Malloc Failure Checks
It's good practice to check ifmallocreturnsNULL(meaning memory allocation failed) to avoid further crashes.
Here's the corrected code for each file:
data.h (fixed syntax errors too!)
struct Sub { int n; struct Sub *next; }; struct Super { struct Sub *Sub; void (*addSub)(struct Super *self, struct Sub *subRef); };
data.c
#include <stdlib.h> #include "data.h" static void addSub(struct Super *self, struct Sub *subRef) { // Initialize the new node's next pointer to NULL subRef->next = NULL; subRef->n = 0; // Optional: Initialize the n value as needed struct Sub *head = self->Sub; // If list is empty, set new node as head if (head == NULL) { self->Sub = subRef; return; } // Traverse to the LAST node (not past it) while (head->next != NULL) { head = head->next; } // Attach the new node to the end head->next = subRef; } struct Super *newSuper() { struct Super *super = malloc(sizeof(struct Super)); if (super == NULL) { // Check if malloc failed return NULL; } super->addSub = addSub; super->Sub = NULL; // Critical: Initialize empty list head return super; }
data_test.c (with safety checks)
#include <stdlib.h> #include "data.h" int main() { struct Super *super = newSuper(); if (super == NULL) { return 1; // Exit if Super allocation failed } struct Sub *newSub = malloc(sizeof(struct Sub)); if (newSub == NULL) { free(super); // Clean up allocated memory before exiting return 1; } super->addSub(super, newSub); // Note: Don't forget to add a cleanup function later to free all nodes! // For example, a freeSuper() that traverses the Sub list and frees each node, then frees super. return 0; }
Quick Notes
- Naming convention: In C, it's standard to use lowercase for variable names (like
subinstead ofSub) to avoid confusion with type names (which are often uppercase or camelCase). You might want to adjust that for readability. - Memory cleanup: Always remember to free allocated memory when you're done with it to prevent memory leaks. Adding a
freeSuperfunction would be a good next step.
内容的提问来源于stack exchange,提问作者Developer

