关于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 公 主 号:程序喵大人,欢迎交流。