C/C++中常见的与存储器有关的错误

来源:互联网 发布:java 将图片写入word 编辑:程序博客网 时间:2024/05/16 08:49

这些都是最近在《深入理解计算机系统》中看到的,在项目中确实很实用

1.间接引用坏指针

在进程的虚拟地址空间中有较大的洞,没有映射任何有意义的数据,如果我们试图间接引用一个指向这些洞的指针,那么操作系统就会以段异常来终止我们的程序。而且,虚拟存储器的某些区域是只读的,试图写这些区域将造成以保护异常终止这个程序。

eg:   scanf("%d", &val)   然而,对于C程序员初学者而言(对有经验者也是如此!), 很容易传递val的内容,而不是它的地址:   scanf("%d", val)

在这种情况下,scanf将把val的内容解释成一个地址,并试图将一个字写到这个位置。在最好的情况下,程序立即以异常终止。最糟糕的情况下,val的内容对应于虚拟存储器的某个合法的读写区域,于是我们就覆盖了存储器,这通常会在相当以后造成灾难性的、令人困惑的后果

2.读为初始化的存储器

malloc的对存储器未初始化为0,建议使用calloc

3.允许栈缓冲区溢出

 程序不检查输入串的大小就写入栈中的目标缓冲区,那么这个程序就会有缓冲区溢出错误

void bufoverflow()

{

   char buf[64];

   gets(buf);

   return;

}建议将gets换成fgets函数,这个函数限制了输入串的大小

4.假设指针和它们指向的对象是相同大小的

  将sizeof(int *)写成了sizeof(int),这个在不同机器上体现的不同

5.造成错位错误

6.引用指针,而不是它所指向的对象

   *size--  由于×与--优先级相同,从右向左结合,这是减少的是指针自己的值,而不是它所指向的整数的值

7.误解指针运算

   p +=sizeof(int)  不等于 p++

8.引用不存在的变量

   int *stackref()

   {

   int val;

   return &val;

   }这个函数返回一个指针(比如说是p),指向栈内的一个局部变量,然后弹出它的栈帧。尽管p仍然指向一个合法的存储器地址,但是它已经不再指向一个合法的变量了。当以后在程序中调用其他函数时,存储器将重用他们的栈帧。后来,如果程序分配某个值给*p,那么它可能实际正在修改另一个函数的栈帧中的一个条目,从而带来潜在的灾难性后果

9.引用空闲堆块中的数据

   引用已经释放的存储器

10.引起存储器泄漏

   malloc后没有free,多次malloc堆里就会充满了垃圾



原创粉丝点击