提问人:altair00 提问时间:9/30/2022 最后编辑:altair00 更新时间:10/1/2022 访问量:240
使用指针,没有使用“free()”,也没有内存泄漏
Using a pointer and did not use `free()` and no memory leaks
问:
在我的程序中,我使用了指针,但我没有用来释放这些内存,我已经用标志编译了,但它说没有内存泄漏。据我所知,如果我分配内存,我还必须在程序结束时释放内存,否则会出现内存泄漏。malloc()
free()
-fsanitize=address
#include <stdio.h>
#include <stdlib.h>
void print2D(int rowSize, int **cols_size, int **arr) {
for(int i = 0; i < rowSize; i++) {
for(int j = 0; j < (*cols_size)[i]; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int** make2D(int rowSize, int **colSize) {
int** arr = (int**) malloc(sizeof(int*) * rowSize);
for(int i=0; i < rowSize; i++) {
arr[i] = (int*) malloc(sizeof(int) * 2);
}
*colSize = (int*) malloc(sizeof(int*) * 2);
(*colSize)[0] = 2;
(*colSize)[1] = 2;
arr[0][0] = 1;
arr[0][1] = 2;
arr[1][0] = 3;
arr[1][1] = 4;
return arr;
}
int main() {
int **colSize;
int rowSize = 2;
int** arr = make2D(rowSize, colSize);
print2D(rowSize, colSize, arr);
return 0;
}
我编译并运行了它gcc -o wow -fsanitize=address wow.c && ./wow
如何没有内存泄漏?我错过了什么吗?
更新
我第一次编译和运行使用,但未能检测到内存泄漏wsl (debian 10)
fsanitize=address
但是当我编译并运行它时检测到.这是为什么呢?Arch 5.19
DEADLYSIGNAL
答:
5赞
ikegami
9/30/2022
#1
编译器不仅会报告泄漏(如果程序设法避免 SIGSEGV),还会报告程序表现出未定义的行为。
$ gcc -Wall -Wextra -pedantic -fsanitize=address a.c -o a && ./a
a.c: In function ‘main’:
a.c:42:17: warning: ‘colSize’ is used uninitialized in this function [-Wuninitialized]
42 | int** arr = make2D(rowSize, colSize);
| ^~~~~~~~~~~~~~~~~~~~~~~~
1 2
3 4
=================================================================
==187==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7fda63d72808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x5594afb0c407 in make2D (/tmp/ikegami/a/a+0x1407)
#2 0x5594afb0c6d6 in main (/tmp/ikegami/a/a+0x16d6)
#3 0x7fda63a97082 in __libc_start_main ../csu/libc-start.c:308
Indirect leak of 16 byte(s) in 2 object(s) allocated from:
#0 0x7fda63d72808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x5594afb0c433 in make2D (/tmp/ikegami/a/a+0x1433)
#2 0x5594afb0c6d6 in main (/tmp/ikegami/a/a+0x16d6)
#3 0x7fda63a97082 in __libc_start_main ../csu/libc-start.c:308
SUMMARY: AddressSanitizer: 32 byte(s) leaked in 3 allocation(s).
要修复未定义的行为,请将
int **colSize;
int rowSize = 2;
int** arr = make2D(rowSize, colSize);
print2D(rowSize, colSize, arr);
跟
int *colSize;
int rowSize = 2;
int** arr = make2D(rowSize, &colSize);
print2D(rowSize, &colSize, arr);
然后你得到
$ gcc -Wall -Wextra -pedantic -fsanitize=address a.c -o a && ./a
1 2
3 4
=================================================================
==249==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7fd485c86808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x55e3c49a8447 in make2D (/tmp/ikegami/a/a+0x1447)
#2 0x55e3c49a8797 in main (/tmp/ikegami/a/a+0x1797)
#3 0x7fd4859ab082 in __libc_start_main ../csu/libc-start.c:308
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7fd485c86808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x55e3c49a84af in make2D (/tmp/ikegami/a/a+0x14af)
#2 0x55e3c49a8797 in main (/tmp/ikegami/a/a+0x1797)
#3 0x7fd4859ab082 in __libc_start_main ../csu/libc-start.c:308
Indirect leak of 16 byte(s) in 2 object(s) allocated from:
#0 0x7fd485c86808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x55e3c49a8473 in make2D (/tmp/ikegami/a/a+0x1473)
#2 0x55e3c49a8797 in main (/tmp/ikegami/a/a+0x1797)
#3 0x7fd4859ab082 in __libc_start_main ../csu/libc-start.c:308
SUMMARY: AddressSanitizer: 48 byte(s) leaked in 4 allocation(s).
您应该更改为 take 而不是 .不需要间接。print2D
const int *cols_size
int **cols_size
评论
0赞
David Ranieri
9/30/2022
这个总和是在修复 UB 后显示的,不是吗?在这种情况下,最好指出这一点,以便 OP 可以推断出由于先前的段错误而未显示泄漏。
0赞
ikegami
9/30/2022
@David Ranieri Re “这个总和是在修复 UB 后显示的,不是吗?”,没有。您可以从警告中清楚地看到 UB 仍然存在,从而引起您对 UB 的注意。
0赞
David Ranieri
9/30/2022
哎呀,奇怪,使用您的命令它显示 AddressSanitizer:DEADLYSIGNAL ================================================================= ==149484==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x556d47bdf499 bp 0x7ffd2662c090 sp 0x7ffd2662c060 T0) 它只显示您在将修复程序应用于 UB 后显示的相同摘要
1赞
ikegami
9/30/2022
@David Ranieri,UB就是这样。你并不总是得到同样的东西:)
1赞
ikegami
9/30/2022
@David Ranieri,我根据您的反馈对我的答案进行了更改。
评论
-fsanitize=address
-fsanitize=leaks
fsanitize=leak
-static-libasan