博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
内存损坏问题的演示样例及分析
阅读量:6073 次
发布时间:2019-06-20

本文共 2465 字,大约阅读时间需要 8 分钟。

以演示样例代码系统的讲述了三种内存损坏的情况: 全局内存、栈损坏及堆损坏, 以及它们产生的原因。

粗略整理例如以下。

Global Memory Corruption

即全局变量的内存使用出了问题,主要还是越界。

例如以下代码:

#include 
#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 
#include
#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 
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 
#include
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://ppngx.baihongyu.com/

你可能感兴趣的文章
带着问题去学习--Nginx配置解析(一)
查看>>
onix-文件系统
查看>>
java.io.Serializable浅析
查看>>
我的友情链接
查看>>
多线程之线程池任务管理通用模板
查看>>
CSS3让长单词与URL地址自动换行——word-wrap属性
查看>>
CodeForces 580B Kefa and Company
查看>>
开发规范浅谈
查看>>
Spark Streaming揭秘 Day29 深入理解Spark2.x中的Structured Streaming
查看>>
鼠标增强软件StrokeIt使用方法
查看>>
本地连接linux虚拟机的方法
查看>>
某公司面试java试题之【二】,看看吧,说不定就是你将要做的题
查看>>
BABOK - 企业分析(Enterprise Analysis)概要
查看>>
Linux 配置vnc,开启linux远程桌面
查看>>
NLog文章系列——如何优化日志性能
查看>>
Hadoop安装测试简单记录
查看>>
CentOS6.4关闭触控板
查看>>
ThreadPoolExecutor线程池运行机制分析-线程复用原理
查看>>
React Native 极光推送填坑(ios)
查看>>
Terratest:一个用于自动化基础设施测试的开源Go库
查看>>