在C++的开发中,我们经常会遇到很多和内存有关的错误。其实使用编译器的一些检查功能,可以帮助我们一定程度上减少这样的错误,下面我们介绍一下
-fsanitize=address
的作用以及一些用法。
1.参数介绍
介绍的部分参考:链接
2.主要检查的方面
- Out-of-bounds accesses to heap, stack and globals
- Use-after-free
- Use-after-return (runtime flag ASAN_OPTIONS=detect_stack_use_after_return=1)
- Use-after-scope (clang flag -fsanitize-address-use-after-scope)
- Double-free, invalid free
- Memory leaks (experimental)
3.代码示例
3.1 检查地址访问越界
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//g++ -O0 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address ./Out_of_bounds.cpp
#include <iostream>
char g_ch[5]={0};
int main(int argc,char * argv[])
{
std::cout << g_ch[5] << std::endl;
char ch_local[6]={0};
std::cout << ch_local[6] << std::endl;
for(int i = 0 ; i 7 ; i++)
{
std::cout << ch_local[i] << std::endl;
}
char * pChar = new char[5];
for(int i = 0 ; i < 7 ; i++)
{
std::cout << pChar[i] << std::endl;
}
delete [] pChar;
return 0;
}
|
程序的输出:
3.2 检查释放后再次使用变量
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//g++ -O0 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address ./Out_of_bounds.cpp
#include iostream>
int main(int argc,char* argv[])
{
char * pChar = new char;
*pChar = '1';
std::cout<< *pChar <<std::endl;
delete pChar;
*pChar = '2';
std::cout << *pChar << std::endl;
return 0;
}
|
程序输出:
3.3 内存泄露
程序代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
//g++ -O0 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address ./Out_of_bounds.cpp
#include <iostream>
void MemLeakOne()
{
char * pChar = new char;
}
void MemLeakTwo(int x)
{
char * pChar = new char;
if(x == 0)
{
delete pChar;
}
}
void MemLeakThree()
{
char * pChar = new char[12];
delete []pChar;
}
int main(int argc,char * argv[])
{
MemLeakOne();
MemLeakTwo(2);
MemLeakThree();
return 0;
}
|
编译警告:
程序输出: