析构函数没有按预期工作,我得到一个分段错误 (C)
Destructor function doesnt work as intended and I get a segmentation fault (C)
我目前正在做一些家庭作业,我需要一些帮助。
函数free_lnode
一旦调用就会触发Segmentation fault(core dumped)
。在核心被转储之前,我收到消息说我正在尝试释放一个未知的指针。
我已经缩小了问题范围并在下面的代码中对其进行了评论,但是我不知道如何修复 free_lnode
函数中的错误。
函数free_lnode
和free_node
的实现需要递归!!!
注意: 我的代码使用了教授库中的 2 个函数:
xcalloc
与 calloc
的工作方式相同,另外它会自行检查 NULL*
s_copy
的工作方式类似于 strcpy
,但是副本是动态分配的
这些函数不是错误的原因,在析构函数中处理。
提前致谢,新年快乐!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
char* value;
int count;
struct Node *next;
} Node;
typedef struct WishList {
Node *first;
char *name;
} WishList;
typedef struct Lnode{
WishList* value;
struct Lnode* next;
} Lnode;
/********* Constructor functions ********/
Lnode* new_lnode(WishList* value, Lnode* next){
Lnode* lnode = xcalloc(1, sizeof(Lnode)); //same as calloc only checks for NULL itself
lnode->value = value;
lnode->next = next;
return lnode;
}
WishList* new_wish_list(char* name, Node* node) {
WishList* list = xcalloc(1, sizeof(WishList)); //same as calloc only checks for NULL itself
list->name = s_copy(name); // s_copy performs dynamic allocation
list->first = node;
return list;
}
Node* new_node(char* value, int count, Node* next) {
Node* node = xcalloc(1, sizeof(Node)); //same as calloc only checks for NULL itself
node->value = s_copy(value); // s_copy performs dynamic allocation
node->count = count;
node->next = next;
return node;
}
/********* Destructor functions ********/
// Recursive destructor function ==> Works
void free_node(Node* node){
if(node->next){
free(node->value);
free_node(node->next);
}
if(node->next == NULL){
free(node->value);
}
free(node);
}
// destructor function ==> Works
void free_wish_list(WishList* list){
free_node(list->first);
free(list->name);
free(list);
}
// Recursive destructor function => TODO: DEBUG
void free_lnode(Lnode* lnode){
if(lnode->next){
printf("DEBUG\n"); // is triggered twice before segmentation is dumped
free_wish_list(lnode->value); //fails to free second wishlist, Console output: trying to free an unknown pointer <some memory location>, segmentation fault (core dumped)
printf("DEBUG\n"); // is only triggered once before segmentation dumped
free_lnode(lnode->next);
}
if(lnode->next == NULL){
free_wish_list(lnode->value);
}
free(lnode);
}
/************************************/
int main(){
Node* a = NULL;
a = new_node("test1", 1, NULL);
Node* b = new_node("test2", 1, a);
Node* c = new_node("test3", 1, b);
Node* d = new_node("test4", 1, c);
Node* e = new_node("test5", 1, d);
WishList* usage_test = new_wish_list("Epic_Test", e);
Node* f = NULL;
f = new_node("test6", 1, NULL);
Node* g = new_node("test7", 1, f);
Node* h = new_node("test8", 1, g);
Node* k = new_node("test9", 1, h);
WishList* usage_test2 = new_wish_list("Epic_Test2", k);
Lnode* new_long_node = new_lnode(usage_test, usage_test2);
free_lnode(new_long_node);
return 0;
}
这里的代码:
Lnode* new_long_node = new_lnode(usage_test, usage_test2);
free_lnode(new_long_node);
是错误的,很容易弄清楚,因为它会发出一个非常明显的警告:
test.c: In function ‘main’:
test.c:105:3: warning: passing argument 2 of ‘new_lnode’ from incompatible pointer type [enabled by default]
test.c:25:8: note: expected ‘struct Lnode *’ but argument is of type ‘struct WishList *’
所以你错误地链接了你的节点。只是从你的 API 推断,我认为你想做这样的事情:
Lnode* new_long_node1 = new_lnode(usage_test, NULL);
Lnode* new_long_node2 = new_lnode(usage_test2, new_long_node1);
free_lnode(new_long_node2);
哦,你的 s_copy
功能实际上是 strdup
而不是 strcopy
。
我目前正在做一些家庭作业,我需要一些帮助。
函数free_lnode
一旦调用就会触发Segmentation fault(core dumped)
。在核心被转储之前,我收到消息说我正在尝试释放一个未知的指针。
我已经缩小了问题范围并在下面的代码中对其进行了评论,但是我不知道如何修复 free_lnode
函数中的错误。
函数free_lnode
和free_node
的实现需要递归!!!
注意: 我的代码使用了教授库中的 2 个函数:
xcalloc
与calloc
的工作方式相同,另外它会自行检查 NULL*s_copy
的工作方式类似于strcpy
,但是副本是动态分配的这些函数不是错误的原因,在析构函数中处理。
提前致谢,新年快乐!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
char* value;
int count;
struct Node *next;
} Node;
typedef struct WishList {
Node *first;
char *name;
} WishList;
typedef struct Lnode{
WishList* value;
struct Lnode* next;
} Lnode;
/********* Constructor functions ********/
Lnode* new_lnode(WishList* value, Lnode* next){
Lnode* lnode = xcalloc(1, sizeof(Lnode)); //same as calloc only checks for NULL itself
lnode->value = value;
lnode->next = next;
return lnode;
}
WishList* new_wish_list(char* name, Node* node) {
WishList* list = xcalloc(1, sizeof(WishList)); //same as calloc only checks for NULL itself
list->name = s_copy(name); // s_copy performs dynamic allocation
list->first = node;
return list;
}
Node* new_node(char* value, int count, Node* next) {
Node* node = xcalloc(1, sizeof(Node)); //same as calloc only checks for NULL itself
node->value = s_copy(value); // s_copy performs dynamic allocation
node->count = count;
node->next = next;
return node;
}
/********* Destructor functions ********/
// Recursive destructor function ==> Works
void free_node(Node* node){
if(node->next){
free(node->value);
free_node(node->next);
}
if(node->next == NULL){
free(node->value);
}
free(node);
}
// destructor function ==> Works
void free_wish_list(WishList* list){
free_node(list->first);
free(list->name);
free(list);
}
// Recursive destructor function => TODO: DEBUG
void free_lnode(Lnode* lnode){
if(lnode->next){
printf("DEBUG\n"); // is triggered twice before segmentation is dumped
free_wish_list(lnode->value); //fails to free second wishlist, Console output: trying to free an unknown pointer <some memory location>, segmentation fault (core dumped)
printf("DEBUG\n"); // is only triggered once before segmentation dumped
free_lnode(lnode->next);
}
if(lnode->next == NULL){
free_wish_list(lnode->value);
}
free(lnode);
}
/************************************/
int main(){
Node* a = NULL;
a = new_node("test1", 1, NULL);
Node* b = new_node("test2", 1, a);
Node* c = new_node("test3", 1, b);
Node* d = new_node("test4", 1, c);
Node* e = new_node("test5", 1, d);
WishList* usage_test = new_wish_list("Epic_Test", e);
Node* f = NULL;
f = new_node("test6", 1, NULL);
Node* g = new_node("test7", 1, f);
Node* h = new_node("test8", 1, g);
Node* k = new_node("test9", 1, h);
WishList* usage_test2 = new_wish_list("Epic_Test2", k);
Lnode* new_long_node = new_lnode(usage_test, usage_test2);
free_lnode(new_long_node);
return 0;
}
这里的代码:
Lnode* new_long_node = new_lnode(usage_test, usage_test2);
free_lnode(new_long_node);
是错误的,很容易弄清楚,因为它会发出一个非常明显的警告:
test.c: In function ‘main’:
test.c:105:3: warning: passing argument 2 of ‘new_lnode’ from incompatible pointer type [enabled by default]
test.c:25:8: note: expected ‘struct Lnode *’ but argument is of type ‘struct WishList *’
所以你错误地链接了你的节点。只是从你的 API 推断,我认为你想做这样的事情:
Lnode* new_long_node1 = new_lnode(usage_test, NULL);
Lnode* new_long_node2 = new_lnode(usage_test2, new_long_node1);
free_lnode(new_long_node2);
哦,你的 s_copy
功能实际上是 strdup
而不是 strcopy
。