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