软件内存使用问题的原理--内存泄露、内存益出、指针操作

发表于:2007-12-24来源:作者:点击数: 标签:
MI LY: 宋体; mso-fareast-font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin; mso-themecolor: text1"

MILY: 宋体; mso-fareast-font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin; mso-themecolor: text1">软件内存问题的原理:(内存泄露、内存益出、指针操作)

一、变量在内存中的存储

# include<stdio.h> //引用头文件stdio.h,这样就可以在程序中调用Printf()函数

Int a=1;    //全局变量a,并赋出值为1

Int b;         //全局变量b

Void main()       //主函数

{

         Int c;         //动态局部变量c,其关键字auto省略

         Static int d;       //静态局部变量d,其关键字static未省略

         Printf(“%d\n”,c)        //打印c的值

}

以上程序段内变量在内存中的存储过程如下:

 


动态局部变量:c    (栈)

(堆)     

静态局部变量;d (静 态存储区域)

全局变量:ab      (静态存储区)

执行语句:printf语句 (代码段)

                                                                         

         在以上过程中:

         栈:存储动态局部变量。

         堆:动态分配的内存空间(手工分配)。

         静态存储区:存储静态局部变量和全局变量,即在整个程序运行期间不变的量。

         代码段:存储执行语句。

二、内存分配形式(CC++JAVA虽然具体语法不同,但内存分配形式都一样)

a)         从静态存储区域分配:内存在编译时就已经分配好,这块内存在程序的整个运行期间都存在,如全局变量,static变量。

b)         在栈上分配:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时,这些存储单元自动被释放掉。栈内存分配运算内置与处理器的指令集。

c)         从堆上分配(动态内存分配):程序在运行时用关键字(mallocnew)申请任意大小的内存,程序员自己负责何时释放内存(freedelete)。动态内存的生存期由程序员决定。

三、程序举例(C语言)

C语言编程时,需要注意的地方

1、  申请内存后,检查内存是否为NULL,防止指针为NULL的内存。

2、  动态内存的申请与释放必须配对,防止内存泄露。

3、  释放内存后,立即将指针设置为NULL,防止产生“野指针”。

4、  不要忘记为数组或动态内存赋出值。

5、  避免数组或指针的下标越界,如多“1”或者少“1”。

# include<malloc.h>         //引用头文件malloc.h,以调用free()函数

#include<stdio.h>    //引用头文件stdio.h,以调用printf()函数

Main()

{

         Char *p;   //定义pchar指针

         P=(char*)malloc(100);     //申请100字节内存空间,并将内存首地址赋值为p

         If(p==null)         //判断P是否为空

                  Printf(“内存未申请成功!!\n”);//如果为空,则内存为空,即内存申请不成功

         Else

                   Printf(“内存首地址为:%X”p);  //将内存首地址已16进制形式输出首地址

                   Free(p);    //释放内存,如果没有这一句,将可能导致内存泄露。

                   P=null;      //指针置为NULL

                   Return 0;

}

以上程序段讲述的是:1-3

#include<stdio.h>    //调用头文件stdio.h

Void main(void)

{

         Int i=0;     //定义变量i,并赋出值为0

         Int a[10]; //定义数组a[],有10个元素,注意这一行有没有问题

         for (i=0;i<10;++i) //循环

                   a[i]=i;        //给数组元素赋值

         for(i=9;i>=0;--i)//循环

                   printf(“%d”,a[i]);      //输出数组元素的值

         printf(“\n”);

}

如果将第一个循环的i<10错误写成i<=10,i<12,此时运行程序将会出现“内存溢出错误”,而且是“写内存溢出”。

如果将第二个循环的i=9错误写成i=10,此时运行程序将会出现一些莫名其妙的数据,这就是“读内存溢出”。

以上程序讲述的是:4-5

原文转自:http://www.ltesting.net