Dynamic memory allocation. The ‘new’ operator Memory allocation for value types, structures, enumerations, objects of classes. Memory allocation for arrays

Dynamic memory allocation. Operator ‘new’. Memory allocation for value types, structures, enumerations, objects of classes. Memory allocation for arrays


Contents


1. How is dynamic memory allocation implemented in C #? The purpose of the ‘new’ operator. General form

In C# programs, memory for objects needs to be allocated dynamically. Dynamic memory allocation for objects or other types of data is implemented using the ‘new’ operator. The general form of the ‘new’ operator

new ClassName(parameters_list)

where

  • ClassName – the name of the class, for the object of which memory is allocated;
  • parameter_list – the list of parameters that one of the class constructors accepts. Necessarily, the constructor must be implemented in class. Parameters of this constructor match with parameter_list. A constructor can be without parameters (default constructor).

 

2. Memory allocation by operator new for an array of objects. General form

The general form of memory allocation for an array of objects, which is an instance of ClassName, is:

new ClassName[size]

where

  • ClassName – the name of the class that is the base type for an array of objects (instances);
  • size – array dimension.

After allocating memory for an array of objects, you need to allocate memory for every object of the class. Otherwise, there will be an exception with the following message:

Object reference not set to an instance of an object

 

3. An example of memory allocation for a single class object

Let a class implementing the general information about a country be given. Class declaration is as follows:

// class that implements general information about country
class Country
{
    string name; // country name
    ulong population; // population
    double square; // country area
    string capital; // capital

    // class constructors
    // constructor without parameters
    public Country()
    {
        name = "";
        population = 0;
        square = 0.0;
        capital = "";
    }

    // constructor with 4 parameters
    public Country(string _name, ulong _population, double _square, string _capital)
    {
        name = _name;
        population = _population;
        square = _square;
        capital = _capital;
    }

    // access methods
    public void Set(string _name, ulong _population, double _square, string _capital)
    {
        name = _name;
        population = _population;
        square = _square;
        capital = _capital;
    }

    public void Get(out string _name, out ulong _population, out double _square, out string _capital)
    {
        _name = name;
        _population = population;
        _square = square;
        _capital = capital;
    }
}

Then the memory allocation for the class and its use can be approximately as follows.

// use of Country class

// memory allocation - the constructor without parameters is called
Country c1 = new Country();

// memory allocation initialized by a 4-parameters constructor
Country c2;
c2 = new Country("Namibia", 2358163, 825418, "Windhoek");

// the use of class c2 methods
string name, cap;
double square;
ulong popul;

c2.Get(out name, out popul, out square, out cap);
// name = "Namibia", popul = 2358163, square = 825418, cap = "Windhoek"

When using the new operator, the corresponding class constructor is invoked. If no constructor is implemented in the class, then the default constructor is called, which has no parameters.

 

4. An example of memory allocation for an array of objects (instances) of a class

Memory for an array of objects of a certain class is allocated in 2 steps. First, memory is allocated for an array of references to class instances. Then, in a loop, memory is allocated for any object (instance) of the class.

Example. Let the class MyClass be given.

// class MyClass
class MyClass
{
    public int d; // internal variable of class
}

The following code allocates memory for an array of MyClass objects. Then memory is allocated for any instance (object) of the class.

...

MyClass[] mc = new MyClass[10]; // memory allocation for the array as a whole

// memory allocation for any object
for (int i = 0; i < 10; i++)
    mcA[i] = new MyClass();

// filling the mc array with squares of numbers from 0 to 9
for (int i = 0; i < 10; i++)
    mcA[i].d = i * i;

...

 

5. An example of allocating memory for a structure

Let a Date structure be given that implements a date.

// structure, that implements a date
struct Date
{
    int day;
    int month;
    int year;

    // constructor of the structure Date
    public Date(int day, int month, int year)
    {
        this.day = day;
        this.month = month;
        this.year = year;
    }

    // method that returns the value of the day, month, year fields
    public void Get(out int d, out int m, out int y)
    {
        d = day;
        m = month;
        y = year;
    }
}

The allocation of memory for a structure variable named dt and the use of a structure variable is:

Date dt = new Date(11, 05, 2008); // memory allocation for a structure variable

int d, m, y;
dt.Get(out d, out m, out y); // get the day of the week: d = 11, m = 5, y = 2008

 

6. An example of memory allocation for an array of structures

Memory allocation for an array of structures is implemented in two stages. First, memory is allocated for an array of variables (references). Then, memory is allocated for each item of the array (each structural variable).

Let the structure Worker be given, which implements the data about the worker:

struct Worker
{
    public string name; // Name and first name of worker
    public int age; // age of worker
    public float rank; // ranking of worker
}

Demonstration of using the array of Worker structures:

Worker[] W; // declaration of a W variable of type array of Worker structures

W = new Worker[20]; // memory allocation for an array of references (objects) to structures

// Allocation of memory for any structure object - it is mandatory
for (int i = 0; i < W.Length; i++)
    W[i] = new Worker();

// Filling the W array with values
for (int i=0; i<W.Length; i++)
{
    W[i].name = "";
    W[i].age = 100;
    W[i].rank = 1.0f;
}

 

7. The example of memory allocation for enumeration

Let there be given a DayWeek enumeration

// DayWeek enumeration
enum DayWeek
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

Memory allocation for a variable of the DayWeek enumeration type and its use may be as follows:

DayWeek dw = new DayWeek();
dw = DayWeek.Monday;
int d = (int)dw; // d = 0

dw = DayWeek.Thursday;
d = (int)dw; // d = 3

 

8. Memory allocation for value types. Examples

The new operator can allocate memory for value types, such as int, double, etc. In this case, the constructor is called, initializing the variable to zero. Calling the new operator for any value type results in a call to the default constructor for that type.

Example 1. Memory allocation for single value types.

// memory allocation for value types
int i = new int();
double d = new double();
bool b = new bool();

i = 23;
d = 7.323;
b = false;

Example 2. Memory allocation for arrays of value types.
The example allocates memory for an array of 20 int numbers and an array of 30 double numbers.

// memory allocation for type-value arrays
int[] A = new int[20]; // array of 20 integers
double[] B = new double[30]; // array of 30 items of double type

// filling arrays with values
for (int j = 0; j < A.Length; j++)
    A[j] = j * j + 2;

for (int j = 0; j < B.Length; j++)
    B[j] = 0.5 * j + 1;

As can be seen from the example, there is no need to allocate memory for each element of the array, as is done in the case of arrays of objects. However, if desired, you can select as shown below.

// memory allocation for each element of array A
for (int j = 0; j < A.Length; j++)
    A[j] = new int();


Related topics