關於C++數組提出幾點問題:ios
先看下這兩段代碼c++
#include <iostream> using namespace std; void func(int num) { int array[num]; // num > 0 cout << "num " << num << endl; cout << "sizeof array " << sizeof(array) << endl; array[0] = 20; cout << "array[0] " << array[0] << endl; } int main() { func(6); return 0; }
輸出:ubuntu
num 6 sizeof array 24 array[0] 20
#include <iostream> using namespace std; void func() { int array[10]; array[3] = 1; array[20] = 3; cout << "sizeof array " << sizeof(array) << endl; cout << "array[3] " << array[3] << endl; cout << "array[20] " << array[20] << endl; } int main() { func(); return 0; }
輸出:數組
sizeof array 40 array[3] 1 array[20] 3
首先分析問題1,咱們平時看書學習過程當中總看見說C++的數組長度必定要是常量且不能是變量,不少資料須要在編譯期肯定棧幀的大小,若是是變量就不能在編譯器肯定棧幀大小,但上述代碼爲何能夠正常運行呢?光看不如實踐,先看這樣一段代碼:函數
#include <iostream> using namespace std; void func2() { int a; int b[4]; int c; cout << "func2a address " << &a << endl; cout << "func2b address " << &b << endl; cout << "func2c address " << &c << endl; // func1(); } void func3(int num) { int a; int b[4]; int c; cout << "func3a address " << &a << endl; cout << "func3b address " << &b << endl; cout << "func3c address " << &c << endl; func2(); } void func4(int num) { int a; int b[4]; int c; cout << "func4a address " << &a << endl; cout << "func4b address " << &b << endl; cout << "func4c address " << &c << endl; func3(num); } int main() { func4(5); return 0; }
輸出:學習
func4a address 0x7ffeb675f418 func4b address 0x7ffeb675f420 func4c address 0x7ffeb675f41c func3a address 0x7ffeb675f3c8 func3b address 0x7ffeb675f3d0 func3c address 0x7ffeb675f3cc func2a address 0x7ffeb675f378 func2b address 0x7ffeb675f380 func2c address 0x7ffeb675f37c
再看這段代碼:spa
void func2() { int a; int b[4]; int c; cout << "func2a address " << &a << endl; cout << "func2b address " << &b << endl; cout << "func2c address " << &c << endl; // func1(); } void func3(int num) { int a; int b[num]; int c; cout << "func3a address " << &a << endl; cout << "func3b address " << &b << endl; cout << "func3c address " << &c << endl; func2(); } void func4(int num) { int a; int b[4]; int c; cout << "func4a address " << &a << endl; cout << "func4b address " << &b << endl; cout << "func4c address " << &c << endl; func3(num); } int main() { func4(100); return 0; }
輸出:3d
func4a address 0x7ffff2c76568 func4b address 0x7ffff2c76570 func4c address 0x7ffff2c7656c func3a address 0x7ffff2c76510 func3b address 0x7ffff2c76360 func3c address 0x7ffff2c76514 func2a address 0x7ffff2c76328 func2b address 0x7ffff2c76330 func2c address 0x7ffff2c7632c
func4a - func3a = 88code
func3a - func2a = 488blog
從上面兩段代碼其實能夠看出C++是支持變量長度的數組的,說不支持的那是很古老的編譯器,在以下連接中也能夠找到答案。
https://c-for-dummies.com/blo...
https://www.drdobbs.com/the-n...
https://stackoverflow.com/que...
備註:儘管C++目前支持變量長度的數組,可是不建議使用,由於數組使用的是棧內存,棧內存是有大小限制的,通常是8192字節,既然長度是變量,那就多是任何值,就有可能超過8192,這樣就會stack overflow,因此動態內存最好使用堆內存。
再分析問題2:操做超過數組長度的內存會發生什麼?看下面這段代碼:
#include <iostream> using namespace std; void func() { int array[10]; array[3] = 1; array[40] = 3; cout << "sizeof array " << sizeof(array) << endl; cout << "array[3] " << array[3] << endl; cout << "array[40] " << array[40] << endl; } int main() { int a[200]; for (int i = 0; i < 200; ++i) { a[i] = 100; } for (int i = 0; i < 200; ++i) { cout << a[i] << " "; } cout << endl << "=====================" << endl; func(); cout << "=====================" << endl; for (int i = 0; i < 200; ++i) { cout << a[i] << " "; } cout << endl << "=====================" << endl; return 0; }
輸出:
root@3eaa9392a3d9:/ubuntu/test_dir# ./a.out 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 ===================== sizeof array 40 array[3] 1 array[40] 3 ===================== 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 3 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 =====================
看代碼輸出,在函數內操做超過數組長度的內存沒有什麼影響,可是它卻致使了上一級的數組a[200]裏的內容被改變,由於數組使用的是棧內存,通過問題1的代碼輸出以及分析能夠看出,棧幀內存是向下增加的,代碼中操做了超過數組長度的內存地址,就影響到了以前棧幀的內存數據,致使以前棧內存數據出現錯誤,可能就會引起大bug。
C++中數組長度能夠是變量,可是不建議使用,由於數組使用的是棧內存,變量能夠是個比較大的數,這樣會致使stack overflow,建議使用堆內存。
操做超過數組長度的內存能夠編譯經過且表面上看不出來問題,可是會致使棧內存出現髒寫,最終可能會引起難以排查的bug,建議數組使用std::array,操做超過長度的下標會拋異常有利於開發者及時發現錯誤。更多文章,請關注個人V X 公 主 號:程序喵大人,歡迎交流。