gpt4 book ai didi

C 内存泄漏 fsanitize=address

转载 作者:行者123 更新时间:2023-11-30 19:29:32 25 4
gpt4 key购买 nike

我正在尝试编写一些代码来创建一个排序的链表,并仅插入唯一元素,以使链表保持排序。另外,我实现了一个函数来删除具有给定值的节点和一个打印它的节点。

我有一些必须运行的测试用例,测试软件需要 main.c 文件和 makefile,并且在 makefile 中我需要使用 fsanitize=address。

没有它,测试用例会通过,但是如果将它包含在 makefile 中,代码将退出并显示消息

"SUMMARY : AddressSanitizer: 64 byte(s) leaked in 4 allocation(s)."

或者类似的东西。可以看出,有的是直接泄漏,有的是间接泄漏。

这是我编写的更新后的代码

#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() 函数中的一些指针分配内存,并且在使用它们后不释放内存...我尝试在使用一些指针后释放内存,但这会导致代码出现另一个问题。

编辑:这里有一些图像,其中包含所使用的输入以及我得到的实际“错误”。

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

请注意,第三个示例没有内存泄漏,并且将通过测试用例。

最佳答案

-fsanitize=address 的作用是什么?

-fsanitize=address(这似乎是 valgrind 的替代品,尽管我不确定到什么程度)检测内存泄漏并在程序退出后报告它。

如果没有此标志(-fsanitize=address),则不会检查内存泄漏;这解释了为什么在没有该标志的情况下编译程序时测试通过而没有内存泄漏摘要。

导致泄漏的原因是什么?

在程序中,内存泄漏的原因有2个。

第一个原因

如果程序在插入一些元素后退出,并且没有显式删除(在每个元素上调用 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;
}

更多关于-fsanitize=address

关于C 内存泄漏 fsanitize=address,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52681467/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com