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的值
}
以上程序段內變量在內存中的存儲過程如下:
|
(堆) |
靜態局部變量;d (靜 態存儲區域) |
全局變量:a、b (靜態存儲區) |
|
在以上過程中:
棧:存儲動態局部變量。
堆:動態分配的內存空間(手工分配)。
靜態存儲區:存儲靜態局部變量和全局變量,即在整個程序運行期間不變的量。
代碼段:存儲執行語句。
二、內存分配形式(C、C++、JAVA雖然具體語法不同,但內存分配形式都一樣)
a) 從靜態存儲區域分配:內存在編譯時就已經分配好,這塊內存在程序的整個運行期間都存在,如全局變量,static變量。
b) 在棧上分配:在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時,這些存儲單元自動被釋放掉。棧內存分配運算內置與處理器的指令集。
c) 從堆上分配(動態內存分配):程序在運行時用關鍵字(malloc、new)申請任意大小的內存,程序員自己負責何時釋放內存(free、delete)。動態內存的生存期由程序員決定。
三、程序舉例(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; //定義p為char指針
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.kjueaiud.com/