分类: C/C++
2009-11-24 17:02:34
此文为原创,转载请注明出处:http://blog.chinaunix.net/u3/93713/showart.php?id=2102742
1. 局部变量太大了容易造成堆栈溢出,比如使用很大的数组。
2. malloc 和 new 之后一定要检查 动态存储区是否申请成功。
3. free 和 delete 释放动态动态存储区后一定要将相应的指针赋值为NULL,即 p=NULL;
4. 数组名是常指针,不能赋值,除非在将数组作为函数参数,这时候数组名退化为指针变量;
5. 中断服务程序ISR应注意的几个问题:1)中断处理程序不能有返回值;2)中断服务程序不能有参数;3)不能有太耗时的操作,比如浮点,或者是长时间延迟,或者是printf函数;4)必须是重入的;
6. 编译器的作用是将C文件转化为汇编文件。
7. 汇编器的作用是将汇编文件转化为二进制指令流*.o文件(目标文件)。
8. 每个目标文件是独立编址的,也就是说每个目标文件的第一个指令都是从相同的地址开始存放的。
9. 连接器的作用是1)将多个目标文件或者库文件按照各文件中的段进行统一的编址;2)生成一个完整的统一的地址映像;3)嵌入式系统中一般生成一个绝对地址映像;4)在有MMU的系统中可以为每个任务单独分配一个地址空间;
10. 程序 = 数据结构 + 算法;
数据结构 = 存储器中的变量 (简单变量,结构体,数组,指针等)
算法 = 存储器中的代码 (指向代码的指针就是函数指针)
11. 看看这段代码有什么问题?
char * DoSomeThing(….)
{
char i[32*1024]; // 问题1
memset(i, 0, 32*1024);
…
…
return i; //问题2
}
问题1:临时变量是通过堆栈实现的,太大的临时变量数组会冲掉堆栈
问题2:返回堆栈中的地址是非常危险的,因为函数返回后堆栈自动销毁,这个时候堆栈中的值是不确定的;
12. 看看这段代码有什么问题?
void DoSomething()
{
int i;
int j;
int k;
memset(&k, 0, 3*sizeof(int));
}
这段代码的作用是将三个临时变量清零;但是这段代码有两个假设:
1) 编译器将i,j,k三个变量通过堆栈表示
2) 压栈顺序是i,j,k(假设堆栈是满递减堆栈)
3) 如果k在寄存器怎么办,对k的取地址操作将产生data abort;
13. 关于临时变量:
1) 不要对临时变量作取地址操作,因为你不知道编译器是否将这个变量映射到了寄存器;
2) 不要返回临时变量地址,或者临时变量的指针,因为堆栈的内容是不确定的(出了这个函数,存放在堆栈里的局部变量就没有意义了);
3) 不要再申请大的临时变量数组,你的临时变量是在堆栈中实现的,你的堆栈有多大呢?、
14. 问题 现在要为一个矩形区域申请一个内存保存这块数据,如果每个pixel占用2bit,如何分配这个内存呢?
答: 应该是char *buffer = malloc(x*y + 1);不能是char *buffer = malloc(x*y);
15. 看看这段代码有什么问题?
char *DoSomething(…..)
{
char *p, *q;
if ((p = malloc(1024)) == NULL) return NULL;
if ((q = malloc(2048)) == NULL) return NULL;
……..
return p;
}
问题在于:如果p申请成功了而q没有申请成功时,应该释放已申请好的p,再返回NULL。
16. 关于动态内存:
1) 总是检查动态内存分配是否成功后再引用该指针;
2) 在分配struct空间时总是使用sizeof
3) 分配内存时 宁滥勿缺 (别忘了加1)
4) 总是free由malloc函数返回的指针
5) 按照 ansi C标准free函数是没有返回值的;
6) 错误处理时不要忘记其他已分配空间的释放,
17. 程序BUG的定位:
1) 关注接口 (好的软件架构总是基于层次性的架构,通过相对单纯的数据结构和接口函数与外界交互)
BUG的定位首先应该从上层向下层排查,将断点设在上层函数的入口,单步执行跟踪程序的流程,特别关注底层函数是否正确(主要是关注它的返回值是否正确),搜索的方位逐渐缩小,最后定位在一个函数内部。
2) 关注内存的访问越界
C语言的灵活性,指针的应用,以及C语法的宽容性很容易造成代码的错误,这其中最主要的就是内存单元的溢出:1)堆栈溢出;2)缓冲区溢出;3)数组越界;因此将错误定位在一个函数内的时候,就应该关注内存的问题了;
18. 关注边界情况
程序中需要考虑的边界情况:1)数组的上限;2)循环的次数;3)链表的头部和尾部在插入新节点,或删除的情况下的特殊处理;4)输入参数的极限情况(0,指针为空,负数,最大的情况等等)。