1. 变量的内存分布:
const变量存储在.rodata(read only)区域;
char* p = "abcd"; p指向的是静态文本区域.text
.rodata 和 .text 被合并为一个segment,由OS保护起来,只可读。
register变量存放在.bss区域;
局部变量存放在栈空间,static变量存放在静态存储空间 (.data)
.bss 和.data 被合并为一个segment,可读可写。
变量在内存中的不同位置,影响着变量的读写方式。程序1很正常,因为p在栈上,可以修改。
view plain
const char * strA() { char p[] = "hello"; p[0] = 'm'; return p; }
程序2就会出错。因为对于全局区域的值,程序员是不可以修改的。
view plainconst char * strA() { char *p = "hello"; //所以我们写用一个指针指向一个字符串时把指针变为常量指针,这样有错误在编译阶段就可以看出。char const * p3 = "hello"; p3[0] = 'm'; 编译不过去。l-value specifies const objectp[0] = 'm'; //虽然编译时没有错误,但运行时报出异常如下图,这样的bug 千万不要留着。运行时的错误很难找出来。return p; }
![5aa7a7138cc43775a4a243858b694475.png](https://i-blog.csdnimg.cn/blog_migrate/e0f889b24b50972752f5161338270663.jpeg)
如果想要修改其值,可以声明为静态变量,这样编译器会在静态存储区域分配一块空间。如程序3:
const char * strA() { static char p[] = "hello"; //注意这里分配的是数组空间,不同于上面的指针。如果是static char * p, 说明指针p占用的4个字节在静态区域可修改,但它所指的内存“hello”仍然在全局区域,不可以修改。 p[0] = 'm'; //OK return p; }
另外,一个类中的静态成员变量时不占这个类的存储空间的。
比如class A{}; class B{static int M;};
sizeof(A) = sizeof(B) = 1
静态成员应该在类定义体的外部初始化。static int B::M = 6;
const成员应该在初始化列表中初始化,除此之外,没有任何地方可以改变它的值。
2.变量的堆栈分布
![35f639a81591e7d570f6041cb7b95c53.png](https://i-blog.csdnimg.cn/blog_migrate/41ec9ff0e401eecf24e9091f5252f113.jpeg)
可以看到栈是从大到校,堆是从小到大。
我们可以通过程序来验证:
#include #include using namespace std; class base { public: void bfun(){} virtual void vfun1(){} virtual int vfun2(){return 0;} base(){ cout<vfun2(); pBase.vfun2(); }int max(int a,int b){if(a>b){return a;}else{return b;}} int main(int argc, char* argv[]) { int a=0;cout<
程序运行结果为:
int 类型变量: 0012FF70//int 肯定是栈里。base constructorderived constructorderived 类型变量取地址: 0012FF64//0012FF64 比int 型变量小所以栈里地址是从大到小。并且发现derived 自定义类型也是在栈里(0012FF64),只有用new 才放在堆里(与java不一样)。base constructorderived constructorderived 指针 p: 00481AF0base constructorderived constructorderived 指针 p1: 00481910Press any key to continue
并且有一点一定要强调,c++ 的new 的只能用指针指向:
int *a=new int[4];//int a[]=new int[4];//cannot convert from 'int *' to 'int []' int *p=a; for(int i=0;i<4;i++){ *p=i; p++;//可以用指针指向访问 } for(int j=0;j<4;j++){ cout<
最后,如果你想学C/C++可以私信小编“01”获取素材资料以及开发工具和听课权限哦!