這裏要搞清楚這個問題,首先咱們要弄清內存的分區,
你們能夠參考這兩篇文章
C++內存分區
C語言詳細內存管理ios
全部的數據都有兩種類型
一是 數據類型
:即咱們的int ,float,double等
二是 存儲類型
:總共有4種存儲類型的變量
自動變量(auto) 寄存器變量(register)
靜態變量(static) 外部變量(extern)ide
寄存器:CPU的一個掛件,速度是最快的
速度比較:寄存器>內存>硬盤(磁盤)
那這些變量用在哪些地方,在哪些位置有效呢?函數
#include <iostream>using namespace std;int * add(int x, int y) {int sum = x + y;return ∑}int * add1(int x, int y) {int *sum = NULL;int a = x + y; sum = &a;return sum;}int main() {int a = 3, b = 5;int* sum = NULL; sum = add(a, b);add1(a, b); cout << *sum << endl;return 0;//sum=add1(a,b)//add(a,b);//cout<<*sum<<endl;//這裏咱們先調用add1結果也會出現錯誤
咱們執行這個代碼會發現怎麼不是8?
3+5不該該是8嗎?怎麼是這麼大一個數字?spa
這裏出現錯誤的緣由就是咱們返回了局部變量的地址,這個sum變量是一個局部變量(即auto自動變量)的有效範圍僅限於函數被調用的時候,當add函數調用結束時 調用add函數用到的棧也會被系統回收,因此咱們再調用add1函數,就把sum所在地址上的內容覆蓋了,改變了原來的值,因此打印出來的就是一個錯誤的答案
.net
可是系統回收後不必定會對棧進行清理或分配給別的函數使用,若是進程再次調用add函數後,系統暫停執行,沒有調用別的函數就不會用到這個棧區,值就不會改變3d
所謂被系統回收的意思是:這段內存不在給add函數使用,而是給同一進程的其餘函數使用
指針
這裏咱們咱們有兩種改進方式code
#include <iostream>using namespace std;int* add1(int x, int y) {int* sum = NULL;int a = x + y; sum = &a;return sum;}int main() {int a = 3, b = 5;int* sum = NULL; sum=add1(a, b); cout << *sum << endl;return 0;}
#include <iostream>using namespace std;int *add(int x, int y) {static int sum = x + y;return ∑}int* add1(int x, int y) {int* sum = NULL;int a = x + y; sum = &a;return sum;}int main() {int a = 3, b = 5;int* sum = NULL; sum=add(a, b);add1(a, b); cout << *sum << endl;return 0;}
這裏咱們使用了靜態變量後,正確打印結果爲8,儘管後面調用了其餘函數
這裏由於靜態變量是在全局靜態區,函數調用結束,它的內存沒有被釋放。blog