我正在尝试编写一些代码来创建排序的链表,并仅插入唯一元素,以使链表保持排序。另外,我实现了一个删除具有给定值的节点并打印该节点的功能。
我有一些必须运行的测试用例,并且测试软件需要main.c文件和一个makefile,并且在makefile中需要使用fsanitize = address。
没有它,测试用例可以通过,但是将其包含在makefile中,代码将退出并显示消息
“摘要:AddressSanitizer:4个分配中泄漏了64个字节。”
或类似的东西。它表明有些是直接泄漏,有些是间接泄漏。
这是我编写的更新的代码。
#include<stdio.h>
#include<stdlib.h>
/* Link list node */
struct Node {
int val;
struct Node* next;
};
void ins(struct Node** head, struct Node* node, int* len) {
// check if the val held by the head is equal to the new node's val
// if it is, return
if(*head != NULL && (*head)->val == node->val) {
free(node);
return;
}
/* Special case for the head end */
if (*head == NULL || (*head)->val > node->val) {
node->next = *head;
*head = node;
// increase the length
(*len)++;
return;
} else {
struct Node* current = *head;
/* Locate the node before the point of insertion */
while (current->next != NULL && current->next->val <= node->val) {
current = current->next;
}
// if the node's val is equal to the val of the node
// in which position it should be inserted, return
if(node->val == current->val) {
return;
}
// add the node into the linked list
node->next = current->next;
current->next = node;
// increment the list's length
(*len)++;
}
}
// delete the value from the linked list
void del(struct Node **head, int value, int* len) {
// Store head node
struct Node* temp = *head;
// If head node itself holds the value to be deleted
if (temp != NULL && temp->val == value) {
// change the head
*head = temp->next;
// decrease the length
(*len)--;
// free the memory and return
free(temp);
return;
}
struct Node* prev;
// Search for the key to be deleted, keep track of the
// previous node as we need to change 'prev->next'
while(temp != NULL && temp->val != value) {
prev = temp;
temp = temp->next;
}
// If key was not present in linked list, return
if(temp == NULL) {
return;
}
// delete the node from the list
prev->next = temp->next;
// decrease length
(*len)--;
free(temp); // Free memory
}
void printList(struct Node *head, int len) {
printf("%d :", len);
struct Node *temp = head;
// print the list's content
while(temp != NULL) {
printf(" %d", temp->val);
temp = temp->next;
}
printf("\n");
}
int main() {
/* Start with an empty list and a temporary node */
struct Node* head = NULL;
struct Node* temp;
int len = 0;
char c;
int value;
// while the input is valid
while(1) {
// check that there is still input
if(scanf(" %c", &c) != 1) {
break;
}
// break out of the loop if the first character is other than i and d
if(c != 'i' && c != 'd') {
break;
}
// read the value
if(scanf("%d", &value) != 1) {
break;
}
// do the required operations
if(c == 'i') {
temp = (struct Node*) malloc(sizeof(struct Node));
// put in the val and set the next to null
temp->val = value;
temp->next = NULL;
ins(&head, temp, &len);
} else if(c == 'd') {
del(&head, value, &len);
}
// print the list
printList(head, len);
}
free(head);
return 0;
}
我尝试修复一些内存泄漏,但似乎仍然存在。我最好的猜测是我正在ins()函数中为某些指针分配内存,并且在使用它们后没有释放内存...我尝试在使用某些指针之后释放内存,但这会导致代码出现另一个问题。 >
编辑:这是一些使用了输入的图像以及我得到的实际“错误”。
请注意,第三个示例没有内存泄漏,将通过测试用例。
答案 0 :(得分:0)
-fsanitize = address (这似乎是valgrind的替代方法,尽管我不确定程度如何)检测到内存泄漏并在程序退出后报告该错误。
没有此标志(-fsanitize = address),将不检查内存泄漏;这解释了为什么在不带标志的情况下编译程序时测试通过并没有内存泄漏摘要的情况。
在程序中,内存泄漏有两个原因。
如果程序在插入一些元素之后退出并且没有显式删除(在每个元素上调用 del())插入的元素,则会导致内存泄漏。
例:i
99
i
101
i
100
q
修复:在 main()中
if(c != 'i' && c != 'd') {
// external inject
temp = head;
while(temp) {
head = head->next;
free(temp);
temp = head;
}
return 0;
}
如果将同一元素插入两次,则第二次插入将失败(保留了唯一性属性),但是未释放分配的内存,则会导致内存泄漏。
例:i
99
i
99
d
99
q
修复:在 ins()中
if(*head != NULL && (*head)->val == node->val) {
// external inject
free(node);
return;
}
.
.
.
if(node->val == current->val) {
// external inject
free(node);
return;
}
的更多信息