原文以示例代码系统的讲述了三种内存损坏的情况: 全局内存、栈损坏及堆损坏, 以及它们产生的原因。粗略整理如下。
即全局变量的内存使用出了问题,主要还是越界。如下代码:
#include <stdio.h>
#define MAX 6
int 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 are 19044 19321 19600 19881 20164 20449
走查代码,你可以发现第一个循环里i的初值是MAX, 应该是MAX-1。 正是这个越界,改写了endval的值。
那个全局变量在内存里是邻居(译注:在我的Mac OS上的输出结果):
(gdb) p &endval $2 = (int *) 0x100001038 (gdb) p &arrdata $3 = (int (*)[6]) 0x100001020
所以arrdat[MAX]的赋值操作,实际变成了对endval的赋值。
这样的破坏操作可以概括为两种:
在*nix系的系统里,Stack会用来存储局部变量, 函数参数以及返回值。栈损坏常常导致未知的行为及崩溃。
栈损坏有两种情况:
越界的情况和之前相似,只是发生在了栈存储的数据上。比如下面的代码 :
#include <stdio.h>
#include <string.h>
#define LEN 6
void 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) r Starting program: /Volumes/Development/Project/Testing/stackcorrupt Reading symbols for shared libraries +.............................. done Program 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)。
出现堆错误,会报臭名昭著的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/
原文:http://blog.csdn.net/horkychen/article/details/37999891