上下文:https://stackoverflow.com/a/73725376/15603477
代码按预期工作。但是,有一个函数没有在整个程序中使用:del_node。试图在case开关选项部分使用它,导致分段错误。
我如何删除链接列表尾部的一个。或者在这个上下文中使用del_node。
主要变更原件为
case 2: /* fallthhrough to 3 intentional until something to do */
更改为
case 2:
del_node(list.tail);
break;
分段故障原因:在主功能情况下,开关部分:两次插入(选项1)〉〉一次删除(选项2)〉〉一次打印输出(选项3)结果:
StudentID: 0, firstname: 1, lastname: 1 class: 1
, graduates: 1
Segmentation fault (core dumped)
所以它确实删除了节点。
完整代码。
/*
https://stackoverflow.com/questions/65223330/function-to-add-a-node-to-linked-list-not-working-c/65226293#65226293
gcc -Wall -Wextra -O3 -pedantic -Wshadow -Ofast \
-Wno-declaration-after-statement \
-fexcess-precision=standard \
-Wmissing-prototypes \
-Wmissing-format-attribute \
linked_list_3.c && ./a.out
valgrind ./a.out
*/
#include "linked_list_3.h"
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<limits.h>
#define MAXC 128
void instructions(void)
{
/* align it so it looks like your menu */
printf( "\nEnter your choice:\n"
" 1. to insert an element into the list.\n"
" 2. to delete an element from the list.\n"
" 3. view list.\n"
" 4. to end.\n\n"
" Your choice: ");
}
/** simple implementation of POSIX strdup() */
char *strdupe(const char *src)
{
char *dst = NULL;
size_t len = strlen(src); /* get length of source */
if(!(dst = malloc(len+1))){ /* allocate/validate destination */
perror("malloc-strdupe");
return NULL;
}
return memcpy(dst,src,len+1);
}
/** create node function, allocates and validates the node and
* each member of student_t requring allocation and set the member
* values to the value provided in the parameters, initializing the
* next/prev pointers NULL. Returns pointer to allocated node on success
* NULL otherwise.
*/
student_t *createnode(char *name,char*lastname,char *class, long studentID,int grad_year)
{
/* allocate for node */
student_t *node = malloc(sizeof *node);
if(!node){
perror("malloc-createnode-dst");
return NULL;
}
node->next = node->prev = NULL;
if(!(node->name = strdupe(name))){ /*from string name to node */
return NULL;
}
if(!(node->lastname = strdupe(lastname))){ /*from string lastname to node */
return NULL;
}
if(!(node->class = strdupe(class))){ /*from string class to node */
return NULL;
}
/* assign remaining member values */
node->studentID = studentID;
node->grad_year = grad_year;
return node; /* return pointer to allocated node */
}
/** must have return type to indicate success/failure of insert.
* you cannot just blindly assume allocations succeed. It's not
* "if", but "when" an allocation fails.
*
* returns pointer to allocated node on success, NULL on failure.
*
*/
student_t *insert(DLL_t *list,char *name,char *lastname
,char *class,long studentID,int grad_year)
{
/* create and validate new node */
student_t *node = createnode(name,lastname,class,studentID,grad_year);
if(!node){
return NULL;
}
if(!list->head) /* if 1st node, node is head/tail */
list->head = list->tail = node;
else {
node->prev = list->tail; /* set prev to tail */
list->tail->next = node; /* add at end, update tail pointer */
list->tail = node;
}
return node;
}
/** print helper for single node */
void prn_node(student_t *node)
{
printf("StudentID: %ld, firstname: %s, lastname: %s class: %s, graduates: %d\n"
,node->studentID,node->name,node->lastname,node->class,node->grad_year);
}
/** print all nodes in list */
void prn_list(DLL_t *list)
{
if(!list->head) {
printf("list empty\n");
return;
}
/* loop over each node in list */
for(student_t *n =list->head; n; n = n->next){
prn_node(n);
}
}
/** delete single node helper */
void del_node(student_t *node)
{
free(node->name);
free(node->lastname);
free(node->class);
free(node);
}
/** delete all nodes in list */
void del_list(DLL_t *list)
{
student_t *n = list->head;
while(n)
{
student_t *victim = n;
n = n->next;
del_node(victim);
}
list->head = list->tail = NULL;
list->maxID = 0;
}
int main(void) /* argument is void if you pass no arguments */
{
char buf[MAXC];
int option;
DLL_t list = {.head = NULL};
while(1)
{
instructions();
if(!fgets(buf,MAXC,stdin)){
printf("user cancelled input\n");
exit(EXIT_SUCCESS);
}
if(sscanf(buf,"%d",&option) != 1){
fprintf(stderr,"error: invalid integer input\n");
exit(EXIT_FAILURE);
}
switch (option)
{
case 1:
{
/* temp storage for strings */
char name[MAXC],lastname[MAXC],class[MAXC];
int grad_year = 0;
/* there is no conversion in the string - no need for printf() */
fputs("enter first name: ",stdout);
if(!fgets(name,MAXC,stdin)){
puts("user cancelled input");
exit(EXIT_FAILURE);
}
name[strcspn(name,"\n")] = 0;
fputs("enter last name: ",stdout);
if(!fgets(lastname,MAXC,stdin)){
puts("user cancelled input");
exit(EXIT_FAILURE);
}
lastname[strcspn(lastname,"\n")] = 0;
fputs("enter class name: ",stdout);
if(!fgets(class,MAXC,stdin)){
puts("user cancelled input");
exit(EXIT_FAILURE);
}
class[strcspn(class,"\n")] = 0;
fputs("enter grad year: ",stdout);
if(!fgets(class,MAXC,stdin)){
puts("user cancelled input");
exit(EXIT_FAILURE);
}
if(sscanf(buf,"%d", &grad_year) != 1){
fprintf(stderr,"error: invalid int input\n");
exit(EXIT_FAILURE);
}
/* validate insertion of values into list */
if(!insert(&list,name,lastname,class,list.maxID,grad_year)){
continue;
}
list.maxID += 1;
break;
}
case 2:
del_node(list.tail);
break;
case 3:
prn_list(&list);
break;
case 4:
goto donelooping;
break;
default:
printf("invalid choice\n");
break;
}
}
donelooping:;
del_list(&list);
exit(EXIT_SUCCESS);
}
1条答案
按热度按时间ulmd4ohb1#
你的
del_node
函数只是一个删除节点的助手,它并不把节点从链表中删除,如果你以后还打算使用链表的话,那么在删除节点之前就需要把节点从链表中删除。