接前一篇的内容,C++中数组在内存中也有静态分配和动态分配的区别。静态数组建立的方式为:A a[],它在栈上分配空间;动态方式是使用new,malloc在堆上分配。
数组要么在静态存储区被创建(如全局数组),要么在栈或堆上被创建。数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。看下例:
1 #include<iostream>
2 using namespace std;
3 void test()
4 {
5 char ch[]="hello";
6 ch[0]='H';
7 char*p="world";
8 p[0]='W';//出错
9 cout<<ch<<endl;
10 cout<<p<<endl;
11 }
12 int main()
13 {
14 test();
15 return 0;
16 }
程序中用指针指向了一个常量字符串"world",C++常量字符串存在常量存储区,且不能修改,故会出错。
数组的在栈上分配,或堆上分配的区别可以看下例:将test和main函数修改为下
1 char* test()
2 {
3 char ch[]="hello";//在栈上
4 /* char* ch= new char[6];//在堆上
5 ch[0]='h';
6 ch[1]='e';
7 ch[2]='l';
8 ch[3]='l';
9 ch[4]='0';
10 ch[5]=' ';
11 */
12 return ch;
13 }
14 int main()
15 {
16 char*p=test();
17 cout<<p<<endl;
18 return 0;
19 }
很明显程序程序编译时出现:warning C4172: returning address of local variable or temporary。在test调用结束后在栈上分配的数组已经销毁,p即为野指针指向无效内容。这里把数组名作为l函数返回值。如果换成下面注释的代码在堆上分配则没有问题,注意最后的' ',字符串的最后是以' '来判断结束的,不然会出界输出无效内容。这里可以看出C++数组在内存中的存储形式与上篇内容介绍的一样。将test改为如下:
1 char* test()
2 {
3 char* ch= new char[6];//在堆上
4 ch[0]='h';
5 ch[1]='e';
6 ch[2]='l';
7 ch[3]='l';
8 ch[4]='0';
9 ch[5]=' ';
10 char c[] = "hello world";
11 char *p = c;
12 cout<< sizeof(c) << endl; // 12字节
13 cout<< sizeof(ch) << endl; // 4字节
14 cout<< sizeof(p) << endl; // 4字节
15 return ch;
16 }
静态数组名用sizeof可以知道数组实际所占的内存大小,而指向数组的指针占用空间即为普通指针的大小。当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
在上一篇关于C++中类在内存中分配的介绍举例时发现一个问题,当两个指针指向同一个对象时,发现delete一个指针销毁该对象后,用另一个指针扔能调用该类的函数,这个是野指针应该有错啊。看下面的例子:
1 #include<iostream>
2 using namespace std;
3 class A
4 {
5 public:
6 void fun()
7 {
8 cout<<"class of a:"<<endl;
9 }
10 int num;
11 };
12 A* test()
13 {
14 A*p;
15 A a;
16 a.num=11;
17 p=&a;
18 p->fun();
19 return p;
20 }
21 int main()
22 {
23 A*s=test();
24 s->fun();
25 return 0;
26 }
程序运行结果:
即两次输出class of a,一次是在test函数内,一次是s调用。test内的a分配在栈上,函数结束后应该就销毁了,为什么s还能调用fun。原来类中的成员数据和函数是存放在不同位置的。C++类的方法存放在"程序代码区",而类中的数据成员(对象数据成员)存放在类的实例对象中,即该成员数据存放在堆或栈中。s指向对象的成员数据已销毁,而类的方法还在。
若将上面代码第8行改为:cout<<"class of a:"<
即s输出的数据成员num为无效,因为该对象已释放。关于C++内存管理还有很多内容,需要进一步加强学习。
原文链接: https://www.cnblogs.com/xiaoxiaoqiang001/p/5562521.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/234654
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!