zoukankan      html  css  js  c++  java
  • Cpp Chapter 9: Memory Models and Namespaces Part3

    9.2.10 Storage schemes and dynamic allocation

    Memory allocated by new operator is called dynamic memory. Dynamic memory is controlled by new and delete operators rather than scope and linkage rules.
    Typically, the compiler has three separate memory chunks: one for static variables, one for automatic variables, one for dynamic storage.
    Suppose you write this:

    float * p_fees = new float [20];
    

    the p_fees pointer still follows the rules of scope and linkage, so you pass the address to another function when using it.
    Memory allocated by new typically is freed when the program terminates. However, the best practice is to use delete to free the memory allocated by new.

    Initialization with the new operator

    in C++11,for built-in types of C++ such as int and double, you use parentheses or braces enclosing the initialization value after the definition:

    int * pi = new int (6);
    double * pd = new double {99.99};
    

    However, for structure or array, only braces are allowed:

    struct where {double x; double y; double z;};
    where * one = new where {2.5, 5.3, 7.2};
    int * ar = new int [4] {2,4,6,7};
    

    For classes with suitable constructors, use parentheses(discussed later).

    When new fails

    When new can't find the requested amount of memory, it throws a std::bad_alloc exception.(discussed later)

    new: Operators, functions, and replacement functions

    new and delete operator call upon two functions:

    void * operator new(std::size_t);
    void * operator new[](std::size_t);
    void operator delete(void *)
    void operator delete[](void *);
    

    std::size_t is a typedef for some suitable integer type.(?) The functions above are collectivly termed allocation functions.

    The placement new operator

    Placement new operator allows you to specify the location to be used. Remember to include header file new when using placement new operator. An example of simple use of placement new operator:

    #include <new>
    struct chaff
    {
        char dross[20];
        int slag;
    };
    char buffer1[50];
    char buffer2[500];
    int main()
    {
        chaff * p1, *p2;
        int *p3, *p4;
        p1 = new chaff;
        p3 = new int[20];
        p2 = new (buffer1) chaff; // allocate p2's content in buffer1
        p4 = new (buffer2) int[20]; // allocate p4's content in buffer2
    }
    

    This code fragment shows the usage of placement new operator. p2 = new (place_supposed) thing; In the example, place_supposed could be an array. An example below:

    // newplace.cpp -- using placement new
    #include <iostream>
    #include <new>
    const int BUF = 512;
    const int N = 5;
    char buffer[BUF];
    int main()
    {
        using namespace std;
        double *pd1, *pd2;
        int i;
        cout << "Calling new and placement new:
    ";
        pd1 = new double[N];
        pd2 = new (buffer) double[N]; // 111111111111111
        for (i = 0; i < N; i++)
            pd2[i] = pd1[i] = 1000 + 20.0 * i;
        cout << "Memory addresses:
    " << "  heap: " << pd1 << "  static: " << (void *) buffer << endl;
        cout << "Memory contents:
    ";
        for (i = 0; i < N; i++)
        {
            cout << pd1[i] << " at " << &pd1[i] << "; ";
            cout << pd2[i] << " at " << &pd2[i] << endl;
        }
    
        cout << "
    Calling new and placement new a second time:
    ";
        double *pd3, *pd4;
        pd3 = new double[N];
        pd4 = new (buffer) double[N]; // 2222222222222
        for (i = 0; i < N; i++)
            pd4[i] = pd3[i] = 1000 + 40.0 * i;
        cout << "Memory contents:
    ";
        for (int i = 0; i < N; i++)
        {
            cout << pd3[i] << " at " << &pd3[i] << "; ";
            cout << pd4[i] << " at " << &pd4[i] << endl;
        }
    
        cout << "
    Calling new and placement new a third time:
    ";
        delete [] pd1;
        pd1 = new double[N];
        pd2 = new (buffer + N * sizeof(double)) double[N]; // 3333333333
        for (i = 0; i < N; i++)
            pd2[i] = pd1[i] = 1000 + 60 * i;
        cout << "Memory contents:
    ";
        for (i = 0; i < N; i++)
        {
            cout << pd1[i] << " at " << &pd1[i] << "; ";
            cout << pd2[i] << " at " << &pd2[i] << endl;
        }
        delete [] pd1;
        delete [] pd3;
        return 0;
    }
    

    This example illustrates 3 facts:

    1. Placement new indeed places the array in the buffer
    2. Placement new simply use the address passed to it. So it might overwrite past data(shown in the code with 11111111 and 2222222222). This feature is also illustrated that in code with 333333333, it uses a new chunk of memory instead of overwriting the previous, due to the fact that address "buffer + N * sizeof(double)" is passed to the placement new.
    3. When you delete a memory allocated by regular new, next new operator will reuse the memory. And, you can't apply delete to replacement new because the memory used by replacement new is predefined, which in this case is buffer, which is undeletable. Applying delete to replacement new will cause runtime error.
      Noteworthy is that using delete to regular new will free the entire block
  • 相关阅读:
    作为一个新手程序员该如何成长?
    不同语言在函数内部定义函数
    展示出版社:写上URL地址对应函数、函数当中查询出所有的出版社、对象交给模板、循环对象拿出每条数据展示
    ORM对象关系映射:
    登录功能和数据库校验:
    登录功能的实现:
    项目那几步走:先配置setting路径文件、创建数据库、执行数据库迁移命令、配置mysql数据库信息、注册app、注释中间件、pymysql替换mysqldb-配置urls路由-继续视图函数-然后HTML页面展示-HTML里面导入css文件、models配置数据库表、
    计算输入的年份是否为闰年,并利用条件运算符输入“是”或者“不是”
    Oracle数据库基本概念理解(3)
    Oracle数据库基本概念理解(3)
  • 原文地址:https://www.cnblogs.com/fsbblogs/p/9746041.html
Copyright © 2011-2022 走看看