c++内存空间

1.内存占用空间

题目:若char是一字节,int是4字节,指针类型是4字节,代码如下:

class CTest
{    
public:  
    CTest():m_chData(‘\0’),m_nData(0){ };        
    virtual void mem_fun(){};    
private:        
    char m_chData;   
    int m_nData;     
    static char s_chData;
};
char CTest::s_chData=’\0’;//静态成员一般不可以在类内初始化,但是const的可以。

问题:
(1)若按4字节对齐sizeof(CTest)的值是多少? 12
(2)若按1字节对齐sizeof(CTest)的值是多少? 9
分析:
1 先找有没有virtual 有的话就要建立虚函数表,+4
2 static的成员变量属于类域,不算入对象中 +0
3 神马成员都没有的类,或者只有成员函数 +1
4 对齐法则(少的算多的)
其他:
1.sizeof的本质是得到某个类型的大小,即创建这个类型的一个对象(或变量)的时候,需要为它分配的空间的大小。
2.static成员变量是存储在静态区当中,是一个共享的量。因此,创建实例对象时,无需再为static成员变量分配空间。
综上,sizeof计算类的大小的时候会忽略static成员变量的大小。


2.变量所在内存空间

C++程序编译后占用的内存分为如下几个部分
1. 栈:由编译器自动分配释放,存放函数的参数值,局部变量的值。在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用。
2. 堆:由程序员分配和释放,若程序员不释放,则程序结束时被OS回收。存放由new,malloc分配的内存,可动态扩展和收缩。
3. 全局区(静态区):全局变量和静态变量的存储是放在一起的初始化的全局变量和初始化的静态变量在一块区域;未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
4. 文字常量区:常量字符串放在这里,程序结束后由系统释放。
5. 程序代码区:存放函数体的二进制代码。

几点说明:
1. 栈效率很高,大小有限:2M。如果分配过多空间,可能导致程序崩溃

例题: func_b 使用了太多的栈,程序可能会在运行时候崩溃。

#define SIZE_20M (20*1024*1024)
void func_b()
{
    char temp[SIZE_20M];
    //...do something using temp
    return;
}
  1. 静态区的成员如果没有初始化,系统会默认初始化。(所以包含全局区。)

堆和栈的主要区别

  1. 管理方式不同:栈由编译器自动管理,无需手动控制;堆由程序员控制,容易产生memory leak。
  2. 能否产生碎片:对于堆来说,频繁地new/delete势必造成内存空间的不连续,从而造成大量碎片,使程序效率降低;对于栈来说,不会存在这个问题,因为栈是后进先出的队列,一一对应,不会出现某个内存块从栈中间弹出。
  3. 生长方向:对于堆来说,生长方向向上,向着内存地址增加的地方;对于栈,生长方向向下,向着内存地址减小的方向。
  4. 分配效率:栈是计算机系统提高的数据结构,操作系统在底层对栈提供支持,分配专门的寄存器存放栈的地址,压栈出栈有专门的指令执行,这就决定了栈的效率比较高。对于堆则是由C/C++函数库提供,显然栈的效率比堆高。

字符串的奇妙空间

1.‘\0’在哪里?

先说一个众所周知的结论:
sizeof()不是函数,是关键字,在编译之时就已经知道了对象的大小。
strlen()求字符串大小时候,只算“\0”之前的。

编号 情况
1 ‘\0’ + 0
2 ‘\0’
3 0

因为’\0’的ASCII码是 0。

2.字符串常量地址

如果有两个指针,都指向一个字符串常量。那么经过编译器优化,两个指针指向的位置通常都是一样的。

猜你喜欢

转载自blog.csdn.net/wushuomin/article/details/80010365
今日推荐