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:\n";
    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:\n" << "  heap: " << pd1 << "  static: " << (void *) buffer << endl;
    cout << "Memory contents:\n";
    for (i = 0; i < N; i++)
    {
        cout << pd1[i] << " at " << &pd1[i] << "; ";
        cout << pd2[i] << " at " << &pd2[i] << endl;
    }

    cout << "\nCalling new and placement new a second time:\n";
    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:\n";
    for (int i = 0; i < N; i++)
    {
        cout << pd3[i] << " at " << &pd3[i] << "; ";
        cout << pd4[i] << " at " << &pd4[i] << endl;
    }

    cout << "\nCalling new and placement new a third time:\n";
    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:\n";
    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

转载于:https://www.cnblogs.com/fsbblogs/p/9746041.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值