(五十九)自动存储、静态存储、动态存储
自動存儲:
函數(shù)內(nèi)部定義的常規(guī)變量,被稱為自動變量,這意味著他們在所屬的函數(shù)被調(diào)用的時候自動產(chǎn)生,在該函數(shù)結(jié)束時消亡。
?
自動變量是一個局部變量,作用域為包含他的代碼塊,比如int?main(){}中定義的int?a;?在int?abc(){}這個函數(shù)中就不能用。
?
自動變量通常儲存在?棧?中,這意味著執(zhí)行代碼塊時,其中的變量將依次加入到?棧?中,而離開代碼塊時,將按相反的順序釋放這些變量,這被稱為后進先出(LIFO),因此,在程序執(zhí)行的過程中,棧將不斷的增大和縮小。
?
靜態(tài)存儲:
靜態(tài)存儲是整個程序執(zhí)行期間都存在的存儲方式。使變量成為靜態(tài)的方式有兩種:
①在函數(shù)外面定義他,比如:
#include <iostream> using namespace std; int a = 1; int main() {cout << a;system("pause");return 0; }②在聲明變量的時候,使用static;如代碼:
static?int?a?=?1;
當(dāng)使用static的時候,能使得函數(shù)在調(diào)用之后,再次調(diào)用的時候,static限定的值能保持在上次調(diào)用之后,函數(shù)的值。如代碼:
#include <iostream> using namespace std; void ab(); int main() {ab(); //調(diào)用函數(shù)abab(); //再次調(diào)用函數(shù)absystem("pause");return 0; }void ab() {static int a = 1; //在第一次起作用的時候a=1,后面再次執(zhí)行的時候不會再次給a賦值為1cout << "調(diào)用ab函數(shù)的時候顯示a的值:" << a << endl;a = a + 1;cout << "a +1 =" << a << endl;; }
輸出:
調(diào)用ab函數(shù)的時候顯示a的值:1 a +1 =2 調(diào)用ab函數(shù)的時候顯示a的值:2 a +1 =3 請按任意鍵繼續(xù). . .
?
我們發(fā)現(xiàn),第一次執(zhí)行函數(shù)ab()的時候,輸出a的值是1,然后在執(zhí)行函數(shù)的時候,a=a+1,于是a=2
當(dāng)?shù)诙螆?zhí)行函數(shù)的時候,a并不是值為1,而是保持了第一次調(diào)用函數(shù)ab()退出時變量a的值,即a=2。
這是static來限定函數(shù)內(nèi)變量的特點,保持函數(shù)變量在退出時的值。
?
?
動態(tài)存儲和內(nèi)存泄露:
new和delete運算符提供了比靜態(tài)變量和自動變量更智能的存儲方式。
?
他們管理了一個內(nèi)存池,這在c++被稱為自由存儲空間(free?store)或堆(heap),該內(nèi)存池與?用于?靜態(tài)存儲?和?動態(tài)存儲?的內(nèi)存是分開的。
?
使用new在堆?上面創(chuàng)建變量,然后再使用delete進行刪除,可以避免內(nèi)存泄露。如果單純使用new,而沒使用delete,那么將會導(dǎo)致new的內(nèi)存地址被占用,在整個程序周期之內(nèi),就無法再次使用這部分內(nèi)存了。在極嚴(yán)重的情況下,很可能導(dǎo)致內(nèi)存被全部用盡,于是程序崩潰。例如代碼:
#include<iostream> char *getname(void); using namespace std;int main() {int i;for (i = 1;i<5;i++){char*a;a = getname(); //這個時候,指針c和指針a的指向內(nèi)存地址是相同的cout << "在主函數(shù)里,把指針c的地址賦給指針a,指針a的值為" << a << endl;cout << "指針a的地址為" << (int*)a << endl; delete[]a; //刪除指針a,因為指針a和指針c指向的內(nèi)存地址相同,相當(dāng)于也delete了指針ccout << endl;}system("pause");return 0; }char*getname() {char*b = new char[20]; //指針b占用了堆中的內(nèi)存空間cout << "隨便輸點什么,別超過20個字符" << endl;cin.get(b, 20).get(); cout << "你輸入的是: " << b << endl; cout << "你輸入的位置所在的內(nèi)存地址為:" << (int*)b << endl; char*c = new char[strlen(b) + 1]; //初始化指針c,并位置new一個新的內(nèi)存地址strcpy_s(c, strlen(b) + 1, b); cout << "將你輸入的字符串復(fù)制到指針c的位置。" << endl;cout << "指針c的地址為:" << (int*)c << endl; cout << "指針c所指向地址的值為" << c << endl; delete[]b; //因為指針c和指針a指向相同,在main函數(shù)中delete指針a,就相當(dāng)于delete了指針c。//但指針b不同,如果不delete指針b,指針b所占用的內(nèi)存空間就一直存在,于是就可能造成內(nèi)存泄露return c; }因為在getname()函數(shù)中,new了2次。在main函數(shù)中new了一次,并delete了一次。
首先,main函數(shù)中的delete了main函數(shù)中new的,
又由于getname()函數(shù)中的指針c和main中的指針a相同,于是相當(dāng)于又delete了一個getname()函數(shù)中的指針,但還存在一個指針b沒有被刪除,這個時候,只有刪除了指針b,才可以避免導(dǎo)致內(nèi)存泄露。
總結(jié)
以上是生活随笔為你收集整理的(五十九)自动存储、静态存储、动态存储的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Intelij idea工具设置片,用6
- 下一篇: 技能UP:SAP CO掌上配置手册