Operators new and delete[]. Memory allocation for structural variables, objects, classes, arrays. Initialization of allocated memory. Example of reallocation of previously allocated memory

Operators new and delete[]. Memory allocation for structural variables, objects of classes, arrays. Initialization of allocated memory. Example of reallocation of previously allocated memory


Contents


1. Example of dynamic allocation of memory for a structured variable

Allocating and releasing memory for a structured variable. Let the structure Date be given, which has the following definition:

// structure that describes the day of the year
struct Date
{
    int day;
    int month;
    int year;
};

Then, to allocate and use the memory for a variable of type struct Date, you need to write approximately the following code:

#include "stdafx.h"
#include <iostream>
using namespace std;

// structure that describes the day of the year
struct Date
{
    int day;
    int month;
    int year;
};

int main()
{
    // allocating memory for a structured variable by the operator new
    struct Date * pd; // pointer to struct Date

    try
    {
        pd = new struct Date; // attempt to allocate memory
    }
    catch (bad_alloc ba)
    {
        cout << "Memory is not allocated" << endl;
        return -1;
    }

    // if memory is allocated, then
    // use pd in program,
    // set the date 11.02.2029
    pd->day = 11;
    pd->month = 2;
    pd->year = 2029;

    cout << pd->month << endl;

    // free the memory used for pd
    delete pd;

    return 0;
}

 

2. Example of dynamic allocation of memory for a class object

The example dynamically allocates memory for a pointer to a CDayWeek class object. The example is implemented for an application such as Console Application.

#include "stdafx.h"
#include <iostream>
using namespace std;

// class that implements the day of the week
class CDayWeek
{
    int d;

    public:
    // constructor
    CDayWeek() { d = 1; }

    // access methods
    int Get(void) { return d; }
    void Set(int nd)
    {
        if ((1<=nd)&&(nd<=7))
            d = nd;
    }
};

int main()
{
    // allocating memory for a class object by the 'new' operator
    CDayWeek *p;

    try
    {
        // attempt to allocate memory for pointer p
        p = new CDayWeek(); // the constructor of class DayWeek is called
    }
    catch (bad_alloc ba)
    {
        cout << "Память не выделена" << endl;
        cout << ba.what() << endl;
        return -1;
    }

    // if memory is not allocated, then use the pointer
    p->Set(3);
    cout << p->Get() << endl;

    // free the memory pointed to by the pointer p
    delete p;

    return 0;
}

 

3. How to allocate memory for an array by the operator new? General form

The new operator can be used to allocate memory for an array. The general form of the ‘new’ operator in the case of allocating memory for an array:

ptrArray = new type[size];

where

  • ptrArray – the name of the array for which memory is allocated;
  • type – the type of array items. The type of elements can be basic (int, float, …) or other (structure, class, etc.);
  • size – array size.

 

4. How to free memory allocated for an array by the delete[] operator? General form

To allocate memory allocated to an array, the delete operator has the following form of use:

delete[] ptrArray;

where ptrArray – The name of the array for which memory is allocated.

 

5. An example of dynamically allocating and freeing memory for an array of pointers to a base type

The example allocates memory for an array of pointers to float. Then the elements of the array are filled with arbitrary values. After that, the allocated memory is released by the delete[] operator.

// declare an array of pointers to a float
float * ptrArray;

ptrArray = new float[10]; // allocate memory for 10 items of float type

// using of array
int d;

for (int i = 0; i < 10; i++)
    ptrArray[i] = i * 2 + 1;

d = ptrArray[3]; // d = 7

delete[] ptrArray; // releasing of memory allocated to an array

 

6. Example of memory allocation for an array of structural variables and its use

The example demonstrates allocating and releasing memory for an array of 3 structures of the TStudent type. Also, ways of accessing the fields of a given element in an array of structures are demonstrated.

#include "stdafx.h"
#include <iostream>
using namespace std;

// structure that defines the information about student
struct TStudent
{
    string name; // name of student
    string numBook; // number of the book
    int course; // course
    float rank; // rating
};

int main()
{
    // allocating memory for an array of structures
    int n_students = 3; // number of students
    TStudent * pS; // pointer, array of structures

    try
    {
        // attempt to allocate memory for an array of structures
        pS = new struct TStudent[n_students];
    }
    catch (bad_alloc ba)
    {
        cout << "Память не выделена." << endl;
        cout << ba.what() << endl;
        return -1;
    }

    // if memory is allocated, then use of array of structures
    // access to an array item with index 0
    pS->name = "Johnson J.";
    pS->numBook = "12389239";
    pS->rank = 3.93;
    pS->course = 4;

    // access to an array item with index 1 - also works
    (pS + 1)->name = "Sullivan";
    (pS + 1)->numBook = "20930032";
    (pS + 1)->rank = 4.98;
    pS[1].course = 3;

    // access to an array item with index 2 - another way
    pS[2].name = "Abram F.D.";
    pS[2].numBook = "l2l28983";
    pS[2].rank = 4.32;
    pS[2].course = 5;

    // output of some values
    cout << pS->name.c_str() << endl; // "Johnson J."
    cout << pS[1].rank << endl;       // 4.98
    cout << (pS + 2)->numBook.c_str() << endl;       // "12128983"

    // free the memory pointed to by the pointer p
    delete[] pS;

    return 0;
}

 

7. An example of allocating and freeing memory for an array of objects. Initializing an array of objects

The example demonstrates allocating memory for an array of objects using the new operator. After using the array, the allocated memory is released by the delete operator.

#include "stdafx.h"
#include <iostream>
using namespace std;

// class that implements the month of the year
class CMonth
{
    private:
    int month;

    public:
    // constructor without parameters, if an array of objects is used,
    // then this constructor is mandatory
    CMonth() { month = 1; }

    // constructor with 1 parameter, to create an array of objects is not suitable,
    // it is suitable only for single objects
    CMonth(int nmonth)
    {
        if ((1 <= nmonth) && (nmonth <= 12))
            month = nmonth;
        else
            month = 1;
    }

    // access methods
    int Get(void) { return month; }
    void Set(int nmonth)
    {
        if ((1 <= nmonth) && (nmonth <= 12))
            month = nmonth;
    }
};

int main()
{
    // allocating memory for an array of class objects
    int nMonths = 12;
    CMonth * pM;

    try
    {
        // attempt to allocate memory for an array of 12 objects
        pM = new CMonth[12]; // For each element, a constructor without parameters is called
    }
    catch (bad_alloc ba)
    {
        cout << "Memory is not allocated" << endl;
        cout << ba.what() << endl;
        return -1;
    }

    // if memory is allocated, then filling the array with values
    for (int i = 1; i <= 12; i++)
        pM[i-1].Set(i);

    // output of some values
    cout << pM[3].Get() << endl; // 4
    cout << pM[5].Get() << endl; // 6

    // free the memory pointed to by the pointer p
    delete[] pM;

    return 0;
}

In the above code, the internal variable in the array of objects is initialized to a value of 1, since this value is specified in the constructor CMonth() without parameters

...

// the constructor without parameters is mandatory, since it acts as an array initializer
CMonth() { month = 1; }

...

This constructor is as initializer for the array. However, one more constructor is implemented in the class: a constructor with 1 parameter or a parameterized constructor. According to the C++ syntax, an array of objects can not be initialized by a parameterized constructor. Therefore, in the CMonth class, a constructor without parameters must be implemented.

If the constructor CMonth() remove from the class code, it will not be possible to allocate memory for the array of objects. It will be possible to allocate memory for single objects, but not for an array.

Conclusion: if you want to allocate memory for an array of objects of a certain class, then this class must necessarily have a constructor implementation without parameters.

 

8. How to reallocate memory if you need to dynamically increase (decrease) the size of the array? Reallocation of memory for structures, the initialization of structures. Example

The example demonstrates the process of reallocating memory for the type of the DayWeek structure. Memory allocation and reallocation dynamically is the main advantage of this method in comparison with static allocation of memory. Memory in the program can be allocated when needed and how much you need.

The structure DayWeek implements a constructor without parameters (by default), which initializes the array of structures with the default value (d = 1).

#include "stdafx.h"
#include <iostream>
using namespace std;

// structure that implements the day of the week
struct DayWeek
{
    int day;

    // structure as a class can also have a constructor
    DayWeek() { day = 1; }
};

int main()
{
    // allocating memory for an array of structures and initializing them
    DayWeek * p;

    try
    {
        // attempt to allocate memory for an array of 5 structures DayWeek
        p = new DayWeek[5];
    }
    catch (bad_alloc ba)
    {
        cout << "Memory is not allocated" << endl;
        cout << ba.what() << endl;
        return -1;
    }

    // if memory is allocated, fill the array with values
    for (int i = 0; i < 5; i++)
        p[i].day = i + 1;

    // using of array
    int d;
    d = (p + 1)->day; // d = 2

    // Demonstration of the increase (reallocation) of memory,
    // it is needed to increase to 7 items in the array
    // 1. Declare a pointer to a new array
    DayWeek * p2;

    try
    {
        // 2. Attempt to allocate memory for a new array (for 7 items)
        p2 = new DayWeek[7];
    }
    catch (bad_alloc ba)
    {
        // if error, then exit with return code -1
        cout << "Memory is not allocated" << endl;
        cout << ba.what() << endl;
        return -1;
    }

    // 3. Save the first 5 items of the old array (copy p => p2)
    for (int i = 0; i < 5; i++)
        p2[i] = p[i];

    // 4. Releasing the memory that was allocated to the old array p
    delete[] p;

    // 5. Redirect the pointer from p to p2.
    p = p2; // Both pointers point to the same memory area

    // 6. Use an array of 7 elements, for example, supplement the last 2
    for (int i = 5; i < 7; i++)
        p[i].day = i + 1;

    d = p[5].day; // d = 6
    d = (p + 6)->day; // d = 7

    // 7. After the work is completed, free the memory for pointer p
    delete[] p; // You could delete[] p2; since p and p2 point to the same memory area

    return 0;
}

The function main() first allocates memory for an array of 5 structures. Then this memory is reallocated for an array of 7 structures. For this, an additional pointer p2 is used.

At reallocation, memory is first allocated for p2 (7 elements). Then the data from p to p2 are copied. After that, the memory that was allocated for pointer p (5 elements) is freed.

In the next step, the value of p is set equal to the value of p2. Thus, both pointers point to the same memory area.

After completing work with the array, the memory for array p is freed.


Related topics