part 1: 介绍
Clang Static Analyzer 和 cppcheck 一样,都是代码静态检查工具。 它是 clang 编译器的一部分,在编译 clang后才能使用。 scan-build 和 scan-view 是用 Perl 写的脚本程序,皆在简化对 Static Analysis 功能 的使用。scan-build 会将结果生保存到 html 中,scan-view 类似一个简单的网页服务器, 可以在浏览器上方便的查看结果。
Part 2: 安装
sudo apt-get install clang
Part 3: 使用
scan-build gcc -c xxx.c
如果测试的代码有bug的话,会生成一个html网页,方便查看,例如:
第一张图提示的Bug类型是“Memory leak”。点击“View Report”可以看到更为细致的出错的地方。以这段代码为例,原因是“square”使用后未能及时分配内存。修改的方式也很简单:
for (int i = 0; i < matrix_size; i++) {
printf("\n");
for (int j = 0; j < matrix_size; j++) {
square[i][j] = i + j;
printf(" %d |", i + j);
}
}
free (square); //free memory after using
}
修改完成后,在使用scan-build可以发现该工具没有提示任何bug。但是这并不代表没有任何逻辑上的漏洞。
#include <stdio.h>
#include <stdlib.h>
#define MAX_LEN 10
void buildMatrix(unsigned int matrix_size) {
char **square = calloc(matrix_size, sizeof(char *));
for (int i = 0; i < matrix_size; ++i) {
square[i] = calloc(matrix_size, sizeof(char));
}
system("cls");
printf("\tMatrix\n");
for (int i = 0; i < matrix_size; i++) {
printf("\n");
for (int j = 0; j < matrix_size; j++) {
square[i][j] = i + j;
printf(" %d |", i + j);
}
}
}
int main() {
int matrix_size = 3;
printf("Enter size of n x n matrix");
scanf("%d", &matrix_size);
if (matrix_size > MAX_LEN) {
printf("Exceeded max length!");
}
buildMatrix(matrix_size);
return 0;
}
为了能够更好的对这段代码进行,我们需要使用 gcc 对该文件输出的a.out文件进行测试:
可以发现,当输入的数值为13时,该代码依然能够执行。但是该代码的限制条件是输入的数字不能大于10。所以修改后的代码如下:
#include <stdio.h>
#include <stdlib.h>
#define MAX_LEN 10
void buildMatrix(unsigned int matrix_size) {
char **square = calloc(matrix_size, sizeof(char *));
for (int i = 0; i < matrix_size; ++i) {
square[i] = calloc(matrix_size, sizeof(char));
}
system("cls");
printf("\tMatrix\n");
for (int i = 0; i < matrix_size; i++) {
printf("\n");
for (int j = 0; j < matrix_size; j++) {
square[i][j] = i + j;
printf(" %d |", i + j);
}
}
free (square);
}
int main() {
int matrix_size = 3;
printf("Enter size of n x n matrix");
scanf("%d", &matrix_size);
if (matrix_size > MAX_LEN) {
printf("Exceeded max length!");
}
else //确保if判定条件生效。
buildMatrix(matrix_size);
return 0;
}