Pointers. Part 5. Memory allocation for the pointer. Arrays of pointers to basic types, functions, structures, classes

Pointers. Part 5. Memory allocation for the pointer. Arrays of pointers to basic types, functions, structures, classes

 


Content
  1. What programming errors can occur when allocating memory for a pointer?
  2. What are the ways to allocate memory for the unmanaged pointer (*)? Example
  3. In which cases is it advisable to use an array of pointers?
  4. What is the general form of describing a one-dimensional array of unmanaged pointers (*)?
  5. Array of pointers to int type. Example
  6. An array of pointers to type double. Example of definition. Example of dynamic allocation of memory for array elements
  7. Array of pointers to char. Example
  8. Example of sorting an array of strings using an unmanaged pointer
  9. How to define an array of unmanaged pointers (*) to a function? Example
  10. Array of unmanaged pointers (*) to the structure
  11. An array of unmanaged pointers (*) to the class. Example of definition and using

 1. What programming errors can occur when allocating memory for a pointer?

 While describing a pointer to a certain type, you must always take care that the pointer points to a variable (object) for which memory should be previously allocated. If this is not done, a critical situation will arise. The example demonstrates an attempt to use two pointers, for one of which is not allocated memory.

Example. Demonstration of allocation of memory for the pointer.

// pointer to int
int * p; // the value of pointer p is still indefinite
int *p2; // The value of p2 is undefined
int x;   // Variable for which memory is allocated

x = 240;
p = &x; // pointer p points to the element for which the memory is allocated
*p = 100; // it works, because p points to x, so x = 100

//*p2 = 100; // Error because p2 points to unknown value

 Let’s explain some fragments of the above example. The example declares two pointers to int

int * p;
int *p2;

After such declaration the pointer value is indefinite. And this means that pointers point to arbitrary parts of memory. If you try to write some constant value into these pointers, for example

*p = 25;
*p2 = 100;

then there will be a critical situation and the system will behave unpredictably. This is explained by the fact that an attempt is made to change the value by a pointer that points to an arbitrary memory location (for example, the pointer points to the program code).

After assignment

p = &x;

The pointer p points to the variable x, for which memory is already allocated. Therefore, the string

*p = 100;

is executed correctly. But a line of code

*p2 = 100;

is an error, since the pointer p2 is not defined.

 

2. What are the ways to allocate memory for the unmanaged pointer (*)? Example

There are 2 ways to allocate memory for the unmanaged pointer:

  • assign the pointer the address of variable for which the memory is already statically allocated;
  • allocate memory dynamically using the new operator;
  • allocate memory dynamically using a special function from the C++ library, for example, malloc().

Example. Methods for allocating memory for a pointer to a double.

double x;
double *p;

// Method 1. Assigning an address to a variable for which memory is already allocated
x = 2.86;
p = &x; // p points to x
*p = -0.85; // x = -0.85

// Method 2. Use the new operator
p = new double;
*p = 9.36;

// Method 3. Use the malloc() function
p = (double *)malloc(sizeof(double));
*p = -90.3;

In the above example, in method 3, to use the malloc() function, you must first connect the <malloc.h> module to the program’s text:

#include <malloc.h>

 

 3. In which cases is it advisable to use an array of pointers?

The use of arrays of pointers is effective in cases when it is necessary to compactly place in memory “extended” data objects, which can be:

  • text strings;
  • structural variables;
  • objects of classes.

An array of pointers helps to save memory and increase performance in the case of variable-length strings.

 

4. What is the general form of describing a one-dimensional array of unmanaged pointers (*)?

General form of defining a one-dimensional array of pointers:

type * name_of_array[size]

where

  • name_of_array – directly the name of the array of pointers;
  • type – type to which the pointers points in the array;
  • size – the size of the array of pointers. In this case, the compiler reserves space for pointers, the number of which is specified in the value of the size. The size is reserved for the pointers themselves and not for the objects (data) to which they point.

 

5. Array of pointers to int type. Example

For each pointer in the array of pointers to the int type can be pre-allocated memory (see p.1).

Example. An array with 10 pointers to int.

// array of pointers to int
int * p[10]; // array of 10 pointers to int
int x;       // Variable to which memory is allocated

x = 240;
p[0] = &x; // this works, the pointer points to the element for which the memory is allocated
*p[0] = 100; // works because p[0] points to x, so x = 100

//*p[1] = 100; // error, since p[1] points an unknown value

 

6. An array of pointers to type double. Example of definition. Example of dynamic allocation of memory for array elements

An array of pointers to real types is declared exactly the same as an integer type (see p.2).

Example. Array of 20 pointers to double type

// array of pointers to double
double *p[20]; // the value of the pointers is undefined
// Memory is allocated dynamically in a loop
for (int i=0; i<20; i++)
{
    p[i] = new double; // dynamic allocation of memory for the pointer
    *p[i] = i+0.5;
}

 

7. Array of pointers to char. Example

Example. Definition array to a char* with simultaneous initialization.

// array of pointers to char
char * ap[] = { "C/C++",
                "Java",
                "C#",
                "Object Pascal",
                "Python" };

// displaying an array of pointers to char in the listBox1 component
String str; // additional variable

listBox1->Items->Clear();
for (int i=0; i<5; i++)
{
    str = gcnew String(ap[i]);
    listBox1->Items->Add(str);
}

In the above example, pointers get an initial value that is equal to the memory address of the corresponding lowercase literal.

 

8. Example of sorting an array of strings using an unmanaged pointer

Using pointers has its advantages if you want to sort arrays of strings. Sorting using pointers is faster because you do not need to copy strings when changing their positions in a string array. In fact, only the most pointers change positions. And this happens faster than rearranging the strings.

Example. Sorting strings by bubble method. A method is proposed without using the function strcmp() from the module <string.h>. Instead, the Compare() function of the System.String class is used. It also demonstrates the display of the rows pointed to by the array of pointers in the listBox1 control (ListBox type).

// array of pointers to char
char * ap[] = { "C/C++",
                "Java",
                "C#",
                "Object Pascal",
                "Python" };
int n = 5; // Number of strings in ap[]

// sorting strings by byble method
for (int i=0; i<n-1; i++)
    for (int j=i; j>=0; j--)
    {
        // additional variables
        String s1 = gcnew String(ap[j]);   // converting from char* to String
        String s2 = gcnew String(ap[j+1]);

        // use the method Compare() from class System.String
        int res; // additional variable
        res = s1->Compare(s1,s2);

        if (res==1) // s1>s2
        {
            // swap the pointers
            char * tp;
            tp = ap[j];
            ap[j] = ap[j+1];
            ap[j+1] = tp;
        }
    }

// displaying an array of pointers to char in the listBox1 component
String str; // additional variable

listBox1->Items->Clear();
for (int i=0; i<5; i++)
{
    str = gcnew String(ap[i]);
    listBox1->Items->Add(str);
}

In the above example, in fact, the pointers are sorted according to the values to which they point.

 

9. How to define an array of unmanaged pointers (*) to a function? Example

An array of unmanaged pointers (*) to a function can be defined only for console applications. If the program is developed using the Windows Forms template in the CLR environment, then you can not use the array of unmanaged pointers (*) to a function.

Let there be given 4 functions that receive two operands of type int and perform the following operations on them:

  • addition, function Add();
  • subtraction, function Sub();
  • multiplications, function Mul();
  • division, function Div().

The implementation of functions is as follows:

// function Add, returns x+y
int Add(int x, int y)
{
    return x+y;
}

// function Sub, returns x-y
int Sub(int x, int y)
{
    return x-y;
}

// function Mul, returns x*y
int Mul(int x, int y)
{
    return x*y;
}

// function Div, returns x/y
int Div(int x, int y)
{
    return (int)(x/y);
}

Demonstration of the function calling through an array of pointers:

// Only for the console application
// array o pointers to a function
int (*p[4])(int, int);
int res_add, res_sub, res_mul, res_div;

p[0] = Add; // p[0] points to Add
res_add = (*p[0])(7, 5); // res = 7+5 = 12

p[1] = Sub; // p[1] points to Sub
res_sub = (*p[1])(7, 5); // res = 7-5 = 2

p[2] = Mul; // p[2] points to Mul
res_mul = (*p[2])(7, 5); // res = 7*5 = 35

p[3] = Div; // p[3] points to Div
res_div = (*p[3])(7, 5); // res = 7/5 = 1

 

10. Array of unmanaged pointers (*) to the structure

In Visual C++, an array of pointers to a structure can be described for both unmanaged pointers (*) and for managed pointers (^). In this example, an array of unmanaged pointers (*) is considered.

More information about the types of pointers in C++ is described here.

Example. Given a structure that defines a point (pixel) on the screen. In the MS Visual Studio environment, if the project is created using the Windows Forms Application template, then the structure should be described outside the main form class of the Form1 program.

// the structure that describes the pixel on the monitor screen
struct MyPoint
{
    int x;
    int y;
    int color; // color
};

If the structure is described in another module, for example “MyStruct.h”, then at the beginning of the file of the main form module, you need to add line

#include "MyStruct.h"

Using an array of pointers to the MyPoint structure:

// unmanaged array of pointers to the structure
MyPoint *p[3];

// allocating memory for an array of structured variables
for (int i=0; i<3; i++)
{
    p[i] = new MyPoint;
}

// filling the values of the fields of structures
for (int i=0; i<3; i++)
{
    p[i]->x = i+5; // random values of x, y, color
    p[i]->y = 2*i+14;
    p[i]->color = i;
}

 

11. An array of unmanaged pointers (*) to the class. Example of definition and using

An array of pointers to a class is defined exactly as an array of pointers to the structure.

Example. Let there be given a class that describes the point on the monitor screen (pixel).

The class is defined in two modules:

  • the module “MyPixelClass.h” defines the declaration of the class, its methods (functions) and fields (internal variables);
  • the module “MyPixelClass.cpp” defines the implementation of the methods (functions) declared in the class (in the module “MyPixelClass.h”).

The text of the module “MyPixelClass.h” (class declaration):

#pragma once

// class is declared without the keyword ref
class MyPixelClass
{
    int x;
    int y;
    int color;

    public:
    MyPixelClass(void);

    int GetX(void);
    int GetY(void);
    int GetColor(void);
    void SetXYColor(int nx, int ny, int nc);
};

The text of the module “MyPixelClass.cpp” (implementation of class):

#include "StdAfx.h"
#include "MyPixelClass.h"

// implementation of methods of class MyPixelClass
MyPixelClass::MyPixelClass(void)
{
    x = y = color = 0;
}

int MyPixelClass::GetX(void)
{
    return x;
}

int MyPixelClass::GetY(void)
{
    return y;
}

int MyPixelClass::GetColor(void)
{
    return color;
}

void MyPixelClass::SetXYColor(int nx, int ny, int nc)
{
    x = nx;
    y = ny;
    color = nc;
}

Demonstration of using an array of pointers to the MyPixelClass class from another program code (for example, the event handler for a click event on a button):

// array of unmanaged pointers to a class
MyPixelClass *mp[5];

// Allocating memory for class objects,
// to which pointers will point
for (int i=0; i<5; i++)
    mp[i] = new MyPixelClass;

// Filling objects of a class with arbitrary values
// demonstration of calling SetXYColor() method
for (int i=0; i<5; i++)
    mp[i]->SetXYColor(i+5, 2*i+8, i);

// demonstration of other class methods
int d;
d = mp[1]->GetX();     // d = 6
d = mp[2]->GetColor(); // d = 2
d = mp[3]->GetY();     // d = 2*3+8 = 14

 


Related topics