内存损坏问题的示例及分析
来源:互联网 发布:淘宝新开店铺找货源 编辑:程序博客网 时间:2024/04/30 00:42
原文以示例代码系统的讲述了三种内存损坏的情况: 全局内存、栈损坏及堆损坏, 以及它们产生的原因。粗略整理如下。
Global Memory Corruption
即全局变量的内存使用出了问题,主要还是越界。如下代码:
#include <stdio.h>#define MAX 6int arrdata[MAX];int endval;int main(){ int i = 0; endval = 12; for (i = MAX; (endval) && (i >= 0) ; i--, endval--) { arrdata[i] = endval * endval; } printf("Values are \n"); for (i = 0; i < MAX; i++) { printf("\t %d\n", arrdata[i]); } return 0;}
编译执行,输出的结果是:
Values are190441932119600198812016420449
走查代码,你可以发现第一个循环里i的初值是MAX, 应该是MAX-1。 正是这个越界,改写了endval的值。
那个全局变量在内存里是邻居(译注:在我的Mac OS上的输出结果):
(gdb) p &endval$2 = (int *) 0x100001038(gdb) p &arrdata$3 = (int (*)[6]) 0x100001020
所以arrdat[MAX]的赋值操作,实际变成了对endval的赋值。
这样的破坏操作可以概括为两种:
- 数组越界,向上或向下(负值).
- 通过指针访问了错误的地址。
Stack Corruption
在*nix系的系统里,Stack会用来存储局部变量, 函数参数以及返回值。栈损坏常常导致未知的行为及崩溃。
栈损坏有两种情况:
- 内存越界操作。
- 栈溢出(stack overflow)。
内存越界
越界的情况和之前相似,只是发生在了栈存储的数据上。比如下面的代码 :
#include <stdio.h>#include <string.h>#define LEN 6void cpyPrint(char *str){ char aBuf[LEN]; strcpy(aBuf, str); printf("String is %s\n", aBuf);}int main(){ char *aStr = "MyLinux"; cpyPrint(aStr); return 0;}
编译执行就会崩溃。下面是在我的Mac OS上的结果:
(gdb) rStarting program: /Volumes/Development/Project/Testing/stackcorruptReading symbols for shared libraries +.............................. doneProgram received signal SIGABRT, Aborted.0x00007fff88815d46 in __kill ()(gdb) bt#0 0x00007fff88815d46 in __kill ()#1 0x00007fff8602d053 in __abort ()#2 0x00007fff85fee74d in __chk_fail ()#3 0x00007fff85feea1f in __strcpy_chk ()#4 0x0000000100000ea6 in cpyPrint (str=0x100000f3e "MyLinux") at stackcorrupt.c:8#5 0x0000000100000ef3 in main () at stackcorrupt.c:17
原因在cpyPrint函数中的局部变量大小为6,却要放进去8个字符(包括一个结束符)。
栈溢出
下面是栈溢出问题的示例代码:
#include <stdio.h>int recur(long int var){ if (var > 0) { recur (var--); } printf("the var is %ld\n", var); return var;}int main(){ recur (3000); return 0;}
这段代码什么时候崩,还要看在运行的系统里的栈大小的设置,可以使用下面的指令直接查到:
$ulimit -s
默认情况下会是8192 (KBytes)。
Heap Corruption
出现堆错误,会报臭名昭著的Segment Fault错误。产生的原因有三种:
- 尝试向已经释放的内存写入数据。
- 越界操作 (的确是最常见的原因)。
- 尝试向尚未分配的内存写入数据。
下面是一个示例:
#include <stdio.h>#include <stdlib.h>int main(){ int *pData = NULL; int num = 12; pData = (int*) malloc (num * sizeof (int)); //...do stuff use the memory free(pData); pData[0] = -1; pData = (int*) malloc (num * sizeof (int)); //...do stuff use the memory free(pData); return 0;}
要想排查内存问题,首选工具自然是Valgrind了,不多做介绍了。
原因链接: http://mylinuxbook.com/memory-corruption-in-linux-programming/
0 0
- 内存损坏问题的示例及分析
- jprofiler主要功能简介及内存泄漏分析示例
- Android内存泄漏问题分析及解决方案
- Android内存泄漏问题分析及解决方案
- ByteArrayInputStream的介绍,源码分析及示例
- SQL数据库损坏及恢复分析
- 结构体中指针赋值问题的分析及C代码示例
- 结构体中指针赋值问题的分析及C代码示例
- 内存损坏
- anroid achartengine折线的示例及问题
- 面向对象的基本概述、内存分析、应用示例
- 内存分配的方式及特点分析
- 内存分配的方式及特点分析
- 关于Android 的内存泄露及分析
- 关于Android 的内存泄露及分析
- 关于Android 的内存泄露及分析
- String及String的内存分析
- 文件系统损坏导致虚拟机无法正常启动的问题及解决方法
- 如何优雅的用20分钟花20块钱搭一个属于自己的网站
- 数组加1问题
- 系统(“暂停”
- 实习面试之——亚信二三事
- UDK——入门开发流程
- 内存损坏问题的示例及分析
- sqlserver 如何带字段注释说明的sql语句
- MyBatis-Spring-SqlSessionFactoryBean
- zoj1649/hdu 1242(Rescue )
- 湖大暑假训练赛2:The Stones Game
- android中listview的性能优化
- 有关nio
- 有趣的问题
- 黑马程序员_JAVA基础-函数与数组