【发布时间】:2021-08-21 09:17:58
【问题描述】:
我不知道是否有其他线程与我的问题,但如果有,我找不到它。
问题是释放链表中现在未使用的单元/节点。 我在当前状态下得到了我预测的确切泄漏量,但是我使用的 2 'free()' 看起来有点过分了,IDE 已经警告我有关释放内存的访问。 (我已经运行了它并且 IDE 是正确的) 那么,如何重写我的代码以真正释放它应该释放的 1 个单元格?
我的节点:
typedef struct node {
char val[2] ; //arrays (in this project of size 2)
struct node * next;
} node_t;
// removes the item at the given position from the list (starting counting from 0)
// memory leakage but idk how to free
node_t* remove_from_list(node_t *head, int index){
node_t *prev = make_list();
printf("prev:");
print_list(prev);
node_t *target = head;
printf("target:");
print_list(target);
// jumping to the location
while (index > 0){
*prev = *target;
target = target->next;
index--;
}
printf("after jump target:");
print_list(target);
printf("new prev:");
print_list(prev);
sleep(1);
//checking if last slot in list
if (is_list_empty(*target) == 2){ //true
printf("last in chain");
sleep(1);
if (is_list_empty(*prev) == 0){ //list of only 1 elem special case
printf("and (0)\n");
sleep(1);
free(prev);
free(target);
return NULL;
}
else{
printf("\n");
prev->next = NULL;
//free(target); <-- this doesnt work
// else c complains that memory used after free
return head;
}
}
//if first in list
if (is_list_empty(*prev) == 0){
printf("first in chain\n");
sleep(1);
head = head->next;
free(prev);
return head;
}
//else
printf("in the middle of chain\n");
*prev->next = *target->next;
printf("new list:\n");
print_list(head);
sleep(1);
//free(target); <-- this doesnt work
return head;
}
此状态下的控制台输出:
(e,f)->(c,d)->(a,b)->(x,y)->
prev:(0)->
target:(e,f)->(c,d)->(a,b)->(x,y)->
after jump target:(c,d)->(a,b)->(x,y)->
new prev:(e,f)->(c,d)->(a,b)->(x,y)->
in the middle of chain
new list:
(e,f)->(a,b)->(x,y)->
(e,f)->(a,b)->(x,y)->
=================================================================
==36817==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7f9b91de5279 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x56450617e2ea in make_list src/llist.c:11
#2 0x56450617e7db in remove_from_list src/llist.c:66
#3 0x56450617f16c in main src/main.c:45
#4 0x7f9b91a1db24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7f9b91de5279 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x56450617e2ea in make_list src/llist.c:11
#2 0x56450617e696 in add_to_list src/llist.c:56
#3 0x56450617f027 in main src/main.c:35
#4 0x7f9b91a1db24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
SUMMARY: AddressSanitizer: 32 byte(s) leaked in 2 allocation(s).
启用免费的控制台输出:
(e,f)->(c,d)->(a,b)->(x,y)->
prev:(0)->
target:(e,f)->(c,d)->(a,b)->(x,y)->
after jump target:(c,d)->(a,b)->(x,y)->
new prev:(e,f)->(c,d)->(a,b)->(x,y)->
in the middle of chain
new list:
(e,f)->(a,b)->(x,y)->
=================================================================
==36962==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000050 at pc 0x5567843aacc0 bp 0x7ffc96b0e130 sp 0x7ffc96b0e120
READ of size 16 at 0x602000000050 thread T0
#0 0x5567843aacbf in print_list src/llist.c:125
#1 0x5567843ab194 in main src/main.c:46
#2 0x7f415e820b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
#3 0x5567843aa1fd in _start (/home/prog2/Project3/RaphDiener/pagerank+0x21fd)
0x602000000050 is located 0 bytes inside of 16-byte region [0x602000000050,0x602000000060)
freed by thread T0 here:
#0 0x7f415ebe7f19 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x5567843aabba in remove_from_list src/llist.c:116
#2 0x5567843ab184 in main src/main.c:45
#3 0x7f415e820b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
previously allocated by thread T0 here:
#0 0x7f415ebe8279 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x5567843aa2ea in make_list src/llist.c:11
#2 0x5567843aa696 in add_to_list src/llist.c:56
#3 0x5567843ab0d1 in main src/main.c:39
#4 0x7f415e820b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
SUMMARY: AddressSanitizer: heap-use-after-free src/llist.c:125 in print_list
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa 00 00 fa fa 00 00 fa fa[fd]fd fa fa 00 00
0x0c047fff8010: fa fa 00 00 fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==36962==ABORTING
【问题讨论】:
-
@Add 这个傻话的目的是什么 node_t *prev = make_list();?!
-
@Add This loop while (index > 0){ *prev = *target;目标=目标->下一个;指数 - ; } 可以在列表中的节点数小于 index 的值时调用未定义的行为。
-
贴出的代码中没有动态内存分配,那么内存泄漏在哪里?
-
@Lundin make_list 呢?:)
标签: c memory-management memory-leaks linked-list singly-linked-list