以下是我的学习笔记
变量错误
一、全局变量
1、定义初始化为0,无初始化,存在与bss段中,在APP中不存在,运行时在展开。(这是由于全局变量,系统也会自动初始话为0)
2、定义初始化非零,存在data段中,因为需要保存初始值,存于APP中
基于此,注意以下亮点
(1)对全局变量的定义初始化时会使APP增大,尤其对大数组,应尽量避免在定义时对它们进行初始化,我们来看下面的一个例子
#include
int arr[1000][1000]={1};
int main()
{
return 0;
}
#include
int arr[1000][1000];
int main()
{
arr[0][0]=1;
return 0;
}比较两者编译后大小,前者远远大于后者
(2)无论是否初始化,全局变量总是会占用运行内存空间,所以尽量避免不必要的大型全局变量。
二、局部变量
局部变量存放在任务栈中
1、在嵌入式设备中,每个任务栈空间被有限,应严格控制栈大小
2、局部内存被返回。局部变量一定不能超过其作用域(小心变相返回,如挂到全局队列中,这个错误很难被发现)
数组和指针的错误
一、访问越界,特别要注意strcpy ‘\0’
二、指针释放的错误
1、释放遗漏 free
2、引用已释放指针(习惯释放后置为NULL),但是这个并不能解决复制指针的问题
3、重复释放(这种情况是比较多的,复杂情况也比较多,往往要全局查找,gdb调试)
4、引用计数的(类似c++中smart指针)
三、指针移位错误,这种较为简单
四、数组和指针的混用(这个需要特别注意)
1、char a[4]="abc" :是一个局部数组,可以修改值
char *b = "abc":是一个全局数组,保存在静态区域,无法修改
我们来看下面的一段代码
#include
int main()
{
char a[4]="abc";
char *b ="abc";
a[2]='d';
printf("%s\n",a);
*(b+1)='d';
printf("%s\n",a);
printf("%s\n",b);
return 0;
}
我们可以看见,编译通过了,但在运行的时候会报段错误。
2、示例 在a.c中定义
#include
char b[4]="123";在b.c中声明并使用b
#include
extern char *b;
int main()
{
char x=b[1];
printf("%d\n",x);
return 0;
}
我们发现,发生了段错误,我们来画个图示
这就不难明白了吧。
3、指针和数组混用的情况
a 指针=数组首地址
b 函数使用数组作为参数时
流程与逻辑错误
一、统计和计数错误
二、分支错误
三 Assert误用
注意 决不能将assert当成错误处理手段,断言用于程序运行过程中不可能发生的情况进行检查。也就是说,只有代码写错才会发生的情况下使用。
a 一些重要指针,检查内部逻辑
b 模块间接口输入参数异常
c 不容许的错误