- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一些代码来创建一个排序的链表,并仅插入唯一元素,以使链表保持排序。另外,我实现了一个函数来删除具有给定值的节点和一个打印它的节点。
我有一些必须运行的测试用例,测试软件需要 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() 函数中的一些指针分配内存,并且在使用它们后不释放内存...我尝试在使用一些指针后释放内存,但这会导致代码出现另一个问题。
编辑:这里有一些图像,其中包含所使用的输入以及我得到的实际“错误”。
请注意,第三个示例没有内存泄漏,并且将通过测试用例。
最佳答案
-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;
}
关于C 内存泄漏 fsanitize=address,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52681467/
我正在尝试使用 conda g++ 编译器使用 -fsanitize=undefined 编译程序。我遇到了“__ubsan_handle_type_mismatch”链接器错误。我在编译和链接中使用
我正在尝试编写一些代码来创建一个排序的链表,并仅插入唯一元素,以使链表保持排序。另外,我实现了一个函数来删除具有给定值的节点和一个打印它的节点。 我有一些必须运行的测试用例,测试软件需要 main.c
使用 -fsanitize 进行编译时,我是否必须使用它来编译每个目标? 我有一些不受它支持的目标(汇编和 C 目标)。 主要可执行文件是受支持的 C++ 文件。 fsanitize 有效吗?或者我需
编译像这样的cpp程序时 int main() { int a[5][5]; cout << a[5][5]; } 使用 -fsanitzie=address 编译时出现运行时异常,但是 in
我想在使用内存清理程序时清除 FD_ZERO 和 FD_SET 上的误报。清除它有点容易: #include ... __msan_unpoison(&readfds, sizeof(readfds
我正在开发一个大型 C++ 项目,用 clang 编译它会很痛苦,所以我坚持使用 GCC。 我想使用很好的 -fsanitize=leak 标志,我在之前的工作中已经与 clang 一起使用过该标志,
我发现这段代码使用“-fsanitize=undefined,address”和不使用它会产生不同的结果。 int printf(const char *, ...); union { long
我在这里有一个小的单元测试,它具有未定义的行为。 源代码: #include TEST(test, test) { int k = 0x7fffffff; k += 1; // ca
我正在使用gcc (SUSE Linux) 7.2.1 20171020编译以下C程序strcmp.c: #include #include int main () { char str1[
我遇到了一个错误无法始终重现,其中 free()在无效的堆指针上调用。对于有问题的代码,根本不可能将此问题减少到“最小”——(一旦我这样做了,它就解决了)。我无法发现任何明显的问题(例如从未调用 ca
当我使用 -fsanitize=address 编译我的 C++ 代码时,我的软件在退出时会打印出泄漏列表。有没有办法避免泄漏报告(我只对内存损坏感兴趣,而不是泄漏)?我用 ASAN flags pa
我正在尝试使用 -fsanitize=bounds 选项找出代码中的越界问题,但我遇到了奇怪的行为: 例如在下面的代码中: #include #include int main (int, cha
将 -fsanitize=address -fno-omit-frame-pointer 与 clang 一起使用时需要注意什么?我经历了一些奇怪的事情debugging behaviour (std
我有一个用 g++ 正常编译的 MEX 文件。 我最近将其编译更改为使用 clang++,并将 -fsanitize=address 包含到 LDFLAGS 和 CFLAGS 中(注意:没有 CXX该
我正在尝试使用 asan 调试 clang 检测到的内存错误,但 valgrind 错过了。但是我无法让我的 clang 构建二进制文件来给我任何有用的调试信息。我可以用一个简短的测试程序来证明这一点
更新(2016 年 9 月 30 日) gcc-6.2 的 Ubuntu 版本((Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901)不再有这个问题。 我正在使用
我想知道 gcc 的 -fsanitize=address 选项与 tcmalloc 一起使用吗?还是我们需要通过禁用 tcmalloc 来运行?或者如果启用 tcmalloc 运行 sanitize
在下面的代码中我遇到了问题。当我给它一个仍然完全为空的 vector 时,代码崩溃,因为 vector.size() - 1 不能为负,因此它环绕。因为 vector 是空的,所以访问 contain
char t = 'a'; char * p1 = &t; char** p2 = &p1; std::cout << p2 << " " << *p2 << " " << **p2 << '\n';
我一直在尝试利用一些 GCC Instrumentation Options用于运行时检查以尝试调试/诊断我在 C++ 代码的特定区域中遇到的问题。 为了尝试缩小问题范围,我开始启用其中一些功能,但在
我是一名优秀的程序员,十分优秀!