C++内存分区(考虑const常量分区)

C++内存分区(考虑const常量分区)

内存分区从低地址到高地址:
.text ->.rodata->.data->.bss->.heap-> .stack->内核空间

分区属性

  • x86 体系下 用户空间3g 内核空间1g 进程的用户空间相互独立,内核空间共享
  • 在stack和heap之间的内存会加载动态链接库,win下 *.dll ,linux下 *.so
  • .text 和 .rodata 内存属性相同 只读不写
  • .data 和 .bss 内存属性相同 可读可写
  • .heap 低地址向高地址增长,由程序员开辟和回收 new/delete malloc/free
  • .stack 操作系统分配和释放 从高地址向低地址增长

内存中堆栈区别:

  • 申请方式不同:栈-系统-申请效率高,堆-程序员-效率低,使用方便但是容易产生碎片。
  • 内存排布不同:栈-连续,堆-不连续
  • 存放内容不同:栈-局部变量,函数参数;堆-由程序员控制

内存分区实践:

C++和C const变量的区别:

  • C中const全局和局部变量的区别:
  • const 修饰的 全局变量 是外部链接, 其他源文件也可以使用 但是在需要使用的源文件进行 extern const int num; 声明
  • const 修饰的 局部变量 在栈区分配内存空间,可以通过变量地址来修改值
  • C++中const全局和局部变量的区别:
  • const 修饰的 全局变量 默认是内部链接,即只能在当前源文件有效,不能直接用于其他源文件,如果想要其他文件也能使用,需要加extern,用c的规则
  • const 修饰的 局部变量 有种说法是不分配内存,会将其放入符号表中,对const 变量 强转取址的时候 才会分配内存,并且通过指针可以修改,cout 指针解引用是修改了的值cout const变量还是原来的值,符号表做了替换
  • const 修饰的 局部的自定义数据类型和数组,系统会分配内存,从而可以通过地址来修改

代码实践

// other.cpp 
extern const int nums = 100; // 用于验证c中的const外部链接
#include
#include
using namespace std;

int g_a = 10; // 全局初始化变量 00007FF7C19CF000
int g_b = 0;// 全部初始化为0的变量 00007FF7C19CF190
int g_c;// 全部未初始化的变量 00007FF7C19CF194

const int g_const_a = 10; // 全局初始化const常量 00007FF7C19CBBB0
const int g_const_b = 0; // 全局未初始化 00007FF7C19CBBB4
//const int g_const_c;// c++规则下必须初始化
static int g_static_a = 11; // 00007FF7C19CF00C  .data
static int g_static_b = 0; //  00007FF7C19CF198  .bass
static int g_static_c;     //  00007FF7C19CF19C  .bss

char g_c_a[] = "aaaa";
char g_c_b = 'a'; // 编译器直接将g_c_b 替换为 a ,不管取值,还是直接 cout都是 a
const char* p = "sss";
char* p2;
int* p3 = new int(2);  // 内存开辟到堆上,但是 p3存储在.bss段,相当于 p3 没有初始化
string str1 = "djklsajd";  // .bss
// c的外部链接全局const
extern const int nums;
int main()
{
    cout << "nums: " << nums << endl; // 可以成功访问 nums=100;

    int l_a = 10;
    int l_b = 0;
    int l_c;
    const int l_const_a = 10;
    const int l_const_b = 0;
    const int l_const_c = 11;
    cout << "查看是否分配内存:" << sizeof(l_const_c) << endl; //4 字节

    static int static_a = 11;
    static int static_b = 0;
    static int static_c;
    char l_c_b[] = "bbbb";

    string str2 = "djasldkj";
   

    cout <<"\n全局局部" << endl;
    cout << &g_a << endl;//00007FF7C19CF000 .data 低地址
    cout << &g_b << endl;//00007FF7C19CF190 .bss  高地址
    cout << &g_c << endl;//00007FF7C19CF194 .bss
    cout <<" 全局常量 " << endl;
    cout << &g_const_a << endl;//00007FF7C19CBBB0 .rodata  地址比.data 还低
    cout << &g_const_b << endl;//00007FF7C19CBBB4 .rodata
    cout <<"\n 全局静态" << endl;
    cout << &g_static_a << endl;//00007FF7C19CF00C .data
    cout << &g_static_b << endl;//00007FF7C19CF198 .bss
    cout << &g_static_c << endl;//00007FF7C19CF19C .bss
    cout << "\n全局字符" << endl;
    cout << &g_c_a << endl;//00007FF7C19CF004  .data
    cout << &"aaaa" << endl;//00007FF7C19CBBB8 .rodata  内存地址和全局const相同,都是只读内存区
    cout << g_c_b << endl;//a  
    
    cout << "\n局部变量" << endl; //产生指令,存放在.text 段 ,只有运行到的时候,函数开辟栈帧,分配局部变量内存
    cout << &l_a << endl;//000000C296B3FAB4 .text
    cout << &l_b << endl;//000000C296B3FAD4 .text
    cout << &l_c << endl;//000000C296B3FAF4 .text
    cout << "\n局部常量" << endl; // 局部的const常量 产生的是指令,对应数据内存存放在栈上
    cout << &l_const_a << endl;//000000C296B3FB14 .text  
    cout << &l_const_b << endl;//000000C296B3FB34 .text

    cout << "\n局部静态变量" << endl; // 局部静态,只有运行到的时候,才会进行初始化
    cout << &static_a << endl;//00007FF7C19CF010 .data 
    cout << &static_b << endl;//00007FF7C19CF1A0 .bass
    cout << &static_c<<"  " << static_c << endl; // 00007FF7C19CF1A4  0   .bass 
    cout << "\n局部字符" << endl;
    cout << &l_c_b << " " << &"bbbb" << endl; //000000C296B3FB54----.text指令, 存放在栈上 00007FF7C19CBE64.rodata 存放在只读内存区中

    cout << "全局字符串指针:" << endl;
    cout << &p << endl; // .data 存放在初始化数据区 .data
    cout << &p2 << endl; // .bss
    cout << &p3 << endl; // .bss
    cout << "全局局部string对象" << endl;
    cout << &str1 << endl; //. bss
    cout << &str2 << endl; // .text
    return 0;
}

欢迎补充指正!

你可能感兴趣的:(C++底层基础,c++,linux,开发语言)