C程序中常见的与存储器有关的错误
2017-08-14 17:31
309 查看
csapp的第九章“虚拟存储器”往往被认为是全书最精华的部分之一。书里前言也写道:“这一章比其他任何一章都更能展现将计算机系统中的硬件和软件结合起来阐述的优点”。在这一章,作者以malloc的实现为例,讲解了动态存储器分配、碎片合并、垃圾回收这些概念。最后列举了十种C程序中容易犯的内存引用错误,很实用:)总结如下。
间接引用坏指针
读未初始化的存储器
允许栈缓冲区溢出
错误地假设指针和它们指向的对象是相同大小的
造成错位错误
引用指针,而不是它所指向的对象
误解指针运算
引用不存在的变量
引用空闲堆块中的数据
引起存储器泄漏
间接引用坏指针
读未初始化的存储器
允许栈缓冲区溢出
错误地假设指针和它们指向的对象是相同大小的
造成错位错误
引用指针,而不是它所指向的对象
误解指针运算
引用不存在的变量
引用空闲堆块中的数据
引起存储器泄漏
间接引用坏指针
读未初始化的存储器
允许栈缓冲区溢出
错误地假设指针和它们指向的对象是相同大小的
造成错位错误
引用指针,而不是它所指向的对象
误解指针运算
引用不存在的变量
引用空闲堆块中的数据
引起存储器泄漏
间接引用坏指针
scanf("%d",&val);//正确,应当传递给scanf变量地址 scanf("%d",val);//错误,scanf会将val值解释为地址,假设不幸的是val的值确实对应于虚存的合法读写区域,就覆盖了存储器
读未初始化的存储器
int *matvec(int **A, int *x, int n) { int i, j; int *y = (int *) malloc(n *sizeof(int)); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { y[i] += A[i][j] * x[j];/* 程序不正确地假设向量y被初始化为零(堆存储器不会初始化为零)*/ } } }
允许栈缓冲区溢出
void bufoverflow() { char buf[64]; gets(buf); /* 不检查输入串的大小就写入栈中的目标缓冲区会导致缓冲区溢出。应使用限制输入串大小的fgets函数 */ return; }
错误地假设指针和它们指向的对象是相同大小的
int **makeArray1(int n, int m) { int i; int **A = (int **) malloc(n * sizeof(int)); /*应是sizeof(int *),否则创建的是int数组而不是指针数组*/ for (i = 0; i < n; i++) A[i] = (int *)malloc(m * sizeof(int)); return A; } /*这段代码将创建一个由n个指针组成的数组,每个指针指向一个包含m个int的数组*/ /*这段代码只有在int和指向int的指针大小相同的机器上运行良好,在指针大于int的机器上会引发for循环写越界*/
造成错位错误
int **makeArray2(int n, int m) { int i; int **A = (int **) malloc(n *sizeof(int *)); for (i = 0; i <= n; i++) /*低级的越界错误,i < n 而不是i <= n */ A[i] = (int *) malloc(m * sizeof(int)); return A; }
引用指针,而不是它所指向的对象
int *binheapDelete(int **binheap, int *size) { int *packet = binheap[0]; binheap[0] = binheap[*size - 1]; *size--; /*注意运算符优先级--和*相同,导致指针自减。应是 (*size)-- */ heapipfy(binheap, *size, 0); return (packet); }
误解指针运算
int *search(int *p, int val) { while (*p && *p != val) p += sizeof(int); /* 指针是以指向的对象大小为单位来进行算术操作的。遍历数组应是p++。*/ return p; }
引用不存在的变量
int *stackref() { int val; return &val; /* 注意局部变量的生存周期 */ }
引用空闲堆块中的数据
int *heapref(int n, int m) { int i; int *x, *y; x = (int *) malloc(n *sizeof(int)); free(x); y = (int *) malloc m * sizeof(int)); for (i = 0; i < m, i++) y[i] = x[i]++; /* x已经被释放 */ return y; }
引起存储器泄漏
void leak(int n) { int *x = (int *)malloc(n *sizeof(int)); return; /* 未释放就返回导致x成为堆中的垃圾 */ }
相关文章推荐
- C程序中常见的存储器有关的错误
- c程序中常见的与存储器有关的错误
- C语言入门程序与存储器常见的有关错误
- C程序中常见的与存储器有关的错误
- 【转】《深入理解计算机系统》C程序中常见的内存操作有关的典型编程错误
- C/C++中常见的与存储器有关的错误
- 【读书笔记】C程序中常见的内存操作有关的典型编程错误
- C 语言程序中与存储器相关的常见错误(即指针相关)
- 错误内存【读书笔记】C程序中常见的内存操作有关的典型编程错误
- 《深入理解计算机系统》C程序中常见的内存操作有关的典型编程错误
- 深入理解计算机系统学习笔记(三)之C语言常见的与存储器(内存)有关的错误
- C/C++程序中常见的与内存有关的错误
- C 语言程序中与存储器相关的常见错误(即指针相关)
- 汇编程序(MASM)常见错误信息
- 多线程Java程序中常见错误的巧处理
- 微信小程序常见错误及基本排除方法
- VS2005开发常见错误及解决(1)VS2005调试程序出错,绑定句柄无效 Terminal Services
- VC++程序常见错误 提示(3)---gyy整理
- VC开发程序,常见C2001,C2005等错误的原因浅析
- 微信小程序常见错误及基本排除方法