#include <stdio.h>
#include <stdlib.h>
// 定义DocNode结构
struct DocNode {
int doc_id;
struct DocNode* next;
};
// 创建新的节点
struct DocNode* create_node(int doc_id) {
struct DocNode* new_node = (struct DocNode*)malloc(sizeof(struct DocNode));
new_node->doc_id = doc_id;
new_node->next = NULL;
return new_node;
}
int main() {
// 定义doc_lists数组,假设有两个链表
int query_count = 2;
struct DocNode* doc_lists[2];
// 初始化第一个链表: 338216 -> 338217 -> 379830
doc_lists[0] = create_node(338216);
doc_lists[0]->next = create_node(338217);
doc_lists[0]->next->next = create_node(379830);
// 初始化第二个链表: 123456 -> 789012
doc_lists[1] = create_node(123456);
doc_lists[1]->next = create_node(789012);
// 输出每个链表的内容
for (int i = 0; i < query_count; i++) {
printf("doc[%d] is: ", i);
struct DocNode* doc_list = doc_lists[i];
while (doc_list) {
printf("%d ", doc_list->doc_id);
doc_list = doc_list->next;
}
printf("\n");
}
// 遍历并释放链表1中的节点
struct DocNode* temp_result = doc_lists[0];
printf("\nReleasing temp_result:\n");
while (temp_result) {
struct DocNode* temp = temp_result;
temp_result = temp_result->next;
printf("%d ", temp->doc_id);
free(temp);
}
printf("\n");
// 再次尝试输出链表内容
printf("\nTo check the result:\n");
for (int i = 0; i < query_count; i++) {
printf("doc[%d] is: ", i);
struct DocNode* doc_list = doc_lists[i];
while (doc_list) {
printf("%d ", doc_list->doc_id);
doc_list = doc_list->next;
}
printf("\n");
}
return 0;
}
The code above has three main parts:
- Output doc_list[0]: The result is doc[0] is:338216 338217 379830
- Assign *temp_result = doc_list[0]: Output each node of temp_result. The result is 338216 338217 379830, and each node of temp_result is freed using free(temp_result).
- Output doc_list[0] again: The result is doc[0] is:0 3
In the last for loop of the code above, if free(temp) is used to release doc_list[0], a double free error occurs. However, if free(temp) is not used to release doc_list[0], running the code multiple times results in a segmentation fault. It is suspected that the linked list is being misused, but it is still unclear why the final output is doc[0] is:0 3 instead of random values.
Possible Cause: Is the issue related to deep copying? (Based on related content, deep copying seems to require implementing a custom function. However, there is concern that deep copying could impact performance in cases involving large amounts of data.)
I am a computer beginner, this is the first time to ask, please forgive me, and sincerely thank you
The last question did not pass, I changed it again (now I put in the modified minimum running code), now the problem is, I want to use a *temp_list=doc_list[0], but my subsequent operation will delete some of the content of temp_list[0], This causes parts of the doc_list[0] to seem to have been modified for some reason. What can I do about this?
Reviewed related materials, which suggest potential solutions for the segmentation fault in such cases, such as "initialize pointers to NULL when created" and "set the pointer to NULL after calling free()." However, these solutions did not resolve the issue.
2 Answers 2
In this code block:
struct DocNode* temp_result = doc_lists[0];
printf("\nReleasing temp_result:\n");
while (temp_result) {
struct DocNode* temp = temp_result;
temp_result = temp_result->next;
printf("%d ", temp->doc_id);
free(temp);
}
you free the linked list held by doc_lists[0] but you never set doc_lists[0] = NULL.
So in the next code block when i is zero, you use a pointer to an object that was free'd.
One solution:
struct DocNode* temp_result = doc_lists[0];
doc_lists[0] = NULL; // <---------------- add this
printf("\nReleasing temp_result:\n");
Comments
First notes:
- Don't cast
malloc,calloc,reallocin C. - Do check the return value from
mallocto ensure it succeeded. - Creating an array of
DocNodepointers then dynamically allocating nodes and linking them together into a list is very odd. This might be worth doing if you were declaring an array ofDocNodestructs to avoid the dynamic allocation, though. query_countshould beconst.
None of these things stop your code from working, and it does compile free of warnings. Good job!
But, free does not have to set a pointer to NULL. as otherwise noted you're using a pointer which has been freed. This results in undefined behavior.
You may wish to modify your code to something like the following.
struct DocNode* temp_result = doc_lists[0];
printf("\nReleasing temp_result:\n");
while (temp_result) {
struct DocNode* temp = temp_result;
struct DocNode** ptr = &temp_result;
temp_result = temp_result->next;
printf("%d ", temp->doc_id);
free(temp);
*ptr = NULL;
}
printf("\n");
Sidenote:
Unless required as part of an academic exercise, in most situation where you need a dynamically sized collection, you probably would be better off with a dynamically resized array which provides O(1) random access and O(1) de-allocation.
Comments
Explore related questions
See similar questions with these tags.
print_listwould be a good function name.free_listwould be another one.