• C++入门5 名字空间|new|虚拟地址


    一,名字空间:namespace

    在C++中支持域:全局域,局部域,块域,名字空间域和类域.

    1,名字空间的使用

    名字空间域是随标准C++而引入的。它相当于一个更加灵活的文件域,使用花括号将文件一部分括起来,并使用关键字namespace开头给它起一个名字:

    1. namespace lkq
    2. {
    3. int a1;
    4. int a2;
    5. int my_add(int a, int b) {
    6. return a + b;
    7. }
    8. }

    花括号括起来的部分称生命块。生命块中可以包括:类,变量(初始化),函数(带定义)。

    最外层的名字空间称为全局名字空间域,即文件域。

    名字空间域的引入,主要是为了解决全局名字空间污染问题,也就是防止程序中全局变量实体名和其他程序中全局变量实体名命名冲突。

    1. //1,普通的命名空间
    2. namespace lkq
    3. {
    4. int a = 10;
    5. int b = 20;
    6. int add(int a, int b) {
    7. return a + b;
    8. }
    9. }
    10. //2,名字空间域可分层嵌套,同样有分层屏蔽左右
    11. namespace lkq
    12. {
    13. int a = 10;
    14. namespace lkq{
    15. int a = 10;
    16. }
    17. }
    18. //同一个工程允许多个相同名称的命名空间
    19. //编译器在最后会合成到同一个命名空间中

    一个名字空间就定义了一个新的作用域,命名空间的所以内容都局限于该空间中。

    2,名字空间的使用

    1,加名字空间及作用域限定符

    1. namespace lkq
    2. {
    3. int a1;
    4. int a2;
    5. int my_add(int a, int b) {
    6. return a + b;
    7. }
    8. }
    9. int main()
    10. {
    11. int a = 10, b = 20;
    12. printf("%d", lkq::my_add(a, b));
    13. return 0;
    14. }

    2,使用using将名字空间中成员引入

    使用using声明可只写一次限定修饰名。using声明以关键字using开头,后面是被限定修饰的名字空间成员名:

    1. using namespace lkq::add;
    2. namespace lkq
    3. {
    4. int a = 10;
    5. int b = 20;
    6. int add(int a, int b)
    7. {
    8. return a + b;
    9. }
    10. }
    11. int main()
    12. {
    13. int c = 10;
    14. int n = 20;
    15. printf("%d\n",add(c,n) );
    16. }

    二,new / delete

    运行程序时,虚拟地址空间

    内核:操作系统

    栈区:函数的形参,非静态的局部变量,函数现场保护数据等等,栈是向下增长的。

    共享库的内存映射区域:用于装在一个共享的动态内存库。用户可使用系统接口创建共享内存,做线程通信。

    堆区:用于程序运行时动态内存分配,堆是可以向上增长的。

    数据区:存储全局数据和静态数据,分为.bss和.data。

    代码段:可执行的程序和常量数据。

    c的动态内存管理:

    c++的动态内存管理:

    1,new运算符的使用

    2,new的函数方法使用

    3,定位new

    4,new和malloc的区别

    1,new是c++的运算符,malloc是函数

    2,malloc申请空间需要手动计算大小,new自动计算大小

    3,malloc申请空间时不会初始化,new可以初始化

    4,malloc的返回值是void*,接收时需要强转,new不需要

    5,malloc申请内存空间失败时返回NULL,使用时必须判空

    new申请内存空间失败抛出异常,所以要有捕获异常状态程序。

    5,从汇编来看new

    1. int main()
    2. {
    3. int* pa=new int;
    4. return 0;
    5. }

    在调试模式下转到反汇编,观察对应的汇编语言:

    这里我们看到,我们调用了new运算符。而编译器在转换的时候调用了一个函数:opreator new的一

    个函数,而这个函数恰恰就是new的底层实现。
     

    我们来看一看operator new函数的源代码实现:

    1. void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
    2. { // try to allocate size bytes
    3. void *p;
    4. while ((p = malloc(size)) == 0)
    5. if (_callnewh(size) == 0)
    6. { // report no memory
    7. static const std::bad_alloc nomem;
    8. _RAISE(nomem);
    9. }
    10. return (p);
    11. }

    从这份源代码可以看出,operator new函数本质也是封装了malloc的函数,并且当申请内存空间失

    败的时候不再是返回NULL,而是抛出异常。可以这么简单认为,operator new函数就是失败抛出

    异常的malloc。

  • 相关阅读:
    VictoriaMetrics之vmalert
    nginx重要配置参数
    Python入门-变量定义与切片&Python引入包和引入模块
    tpwe兼容微擎小程序前端请求写法
    数据仓库面试题——介绍下数据仓库
    使用MySQL,请用好 JSON 这张牌
    【UNI】底部梯形按钮组件
    如何在Windows中使用C#填写和提取PDF表单
    MSP432单片机学习记录(二)
    如何写出新闻营销中的优质新闻稿?企业在做新闻营销需要注意哪些问题呢?
  • 原文地址:https://blog.csdn.net/2303_76580416/article/details/139331312