c++中不同的数据区
来源:互联网 发布:logo制作软件怎么用 编辑:程序博客网 时间:2024/06/03 16:52
c++中内存分配的问题。
注意:1)全局变量以及静态变量存放在静态数据区;
2)注意常量的存放区域,通常情况下,常量存放在程序区(程序区是只读的,因此任何修改常量的行为都是非法的),而不是数据区。有的系统,也将部分常量分配到静态数据区,比如字符串常量(有的系统也将其分配在程序区)。但是要记住一点,常量所在的内存空间都是受系统保护的,不能修改。对常量空间的修改将造成访问内存出错,一般系统都会提示。常量的生命周期一直到程序执行结束为止。
1.test1
#include<iostream>using namespace std;void test(int *p){ int b=2; p=&b; cout<<p<<endl;}int main(void){ int a=10; int *p=&a; cout<<p<<endl; test(p); cout<<p<<endl; return 0;}
第一行输出和第三行输出的结果相同,而第一行、第三行与第二行输出的结果不同。从这里可以看出,当指针作为参数进行传递时传递的也只是一个值,只不过该值只一个地址,因此对于形参的改变并不影响实参。
2.test2
#include<iostream>using namespace std;char* test(void){ char str[]="hello world!"; return str;}int main(void){ char *p; p=test(); cout<<p<<endl; return 0;}
输出结果可能是hello world!,也可能是乱麻。
出现这种情况的原因在于:在test函数内部声明的str数组以及它的值"hello world”是在栈上保存的,当用return将str的值返回时,将str的值拷贝一份传回,当test函数执行结束后,会自动释放栈上的空间,即存放hello world的单元可能被重新写入数据,因此虽然main函数中的指针p是指向存放hello world的单元,但是无法保证test函数执行完后该存储单元里面存放的还是hello world,所以打印出的结果有时候是hello world,有时候是乱麻。
3.test3
#include<iostream>using namespace std;int test(void){ int a=1; return a;}int main(void){ int b; b=test(); cout<<b<<endl; return 0;}
输出结果为 1
有人会问为什么这里传回来的值可以正确打印出来,不是栈会被刷新内容么?是的,确实,在test函数执行完后,存放a值的单元是可能会被重写,但是在函数执行return时,会创建一个int型的零时变量,将a的值复制拷贝给该零时变量,因此返回后能够得到正确的值,即使存放a值的单元被重写数据,但是不会受到影响。
4.test4
#include<iostream>using namespace std;char* test(void){ char *p="hello world!"; return p;}int main(void){ char *str; str=test(); cout<<str<<endl; return 0;}
执行结果是 hello world!
同样返回的是指针,为什么这里会正确地打印出hello world1?这是因为char *p="hello world!",指针p是存放在栈上的,但是"hello world!”是一个常量字符串,因此存放在常量区,而常量区的变量的生存期与整个程序执行的生命期是一样的,因此在test函数执行完后,str指向存放“hello world!”的单元,并且该单元里的内容在程序没有执行完是不会被修改的,因此可以正确输出结果。
5.test5
#include<iostream>using namespace std;char* test(void){ char *p=(char *)malloc(sizeof(char)*100); strcpy(p,"hello world"); return p;}int main(void){ char *str; str=test(); cout<<str<<endl; return 0;}
运行结果 hello world
这种情况下同样可以输出正确的结果,是因为是用malloc在堆上申请的空间,这部分空间是由程序员自己管理的,如果程序员没有手动释放堆区的空间,那么存储单元里的内容是不会被重写的,因此可以正确输出结果。
6.test6
#include<iostream>using namespace std;void test(void){ char *p=(char *)malloc(sizeof(char)*100); strcpy(p,"hello world"); free(p); if(p==NULL) { cout<<"NULL"<<endl; }}int main(void){ test(); return 0;}
没有输出
在这里注意了,free()释放的是指针指向的内存!注意!释放的是内存,不是指针!这点非常非常重 要!指针是一个变量,只有程序结束时才被销毁。释放了内存空间后,原来指向这块空间的指针还是存在!只不过现在指针指向的内容的垃圾,是未定义的,所以说是垃圾。因此,释放内存后应把把指针指向NULL,防止指针在后面不小心又被使用,造成无法估计的后果
- c++中不同的数据区
- C++中不同的数据区
- c语言中format不同的数据匹配的不同数据格式
- 找出一组数据中不同的数据
- C中^和Java中^的不同
- 【c#】 5. Tensor数据(用于Excel中不同sheet中都有矩阵的情况)
- 不同的Activity中传递数据
- Mysql中数据切分的不同形式
- Dialog中 不同Recycleview的数据交互
- C/C++中 const的不同含义
- c和c++中goto的不同
- C语言中,整形、浮点型、字符型数据在不同编译器中所占据的字节数
- ABAP中读取EXCEL中不同的SHEET数据
- ABAP中读取EXCEL中不同的SHEET数据
- ABAP中读取EXCEL中不同的SHEET数据
- sql中查找两个表中不同的数据
- C语言同时向不同的文件写入不同的数据
- c中字符串与c++中字符串的不同
- wpf 画面上显示时钟
- 《那些年啊,那些事——一个程序员的奋斗史》五
- 基于ALSA架构的声卡播放录音设置
- 一个Linux下C线程池的实现(转)
- MFC--用SkinMagicSDK换皮肤
- c++中不同的数据区
- 从一个职校走出来的微软最有价值专家(Microsoft MVP)
- c++堆栈
- C#连接MySQL
- ExtJs2.0学习系列(7)--Ext.TabPanel
- SQL 左外连接,右外连接,全连接,内连接
- C#中使用委托创建事件实现两个窗体间通信
- ATL Internals 2ed复习.chapter 5.CAtlModule
- PL/SQL Developer 注册码