Last modified: Mon, 11 Oct 2010 18:25:38 +0300
Complete: ###################- (95%)
2.1 Introduction
2.2 new and delete Operators
2.3 Dynamic Matrices
2.4 Dynamic Memory Management in ANSI-C
2.5 Examples
2.6 Exercises
2.1 Introduction
In a C++ program, when the size of array and its dimension (number of elements) are declared, the compiler allocates a memory
location for the array where the array is stored during the execution of the program. This location cannot be used for any other purpose.
These type of arrays are called static arrays. Normally, the size of a static array may not be changed during run time.
We discussed static arrays in topic 7 of
the basic tutorial section.
However, C++ provides run-time or dynamic arrays for which memory is allocated during executation
(i.e. run-time allocation). If the required size of an array is unknown at compile time then a dynamic array should be used.
In this section, we will mention about creating dynamic arrays or dynamic memory management.
[we need to mention the option of using the vector class, we can link to this when that section of the basic tutorial is ready, and
explain a little about why we would use new,delete instead of vectors]
2.2 new and delete Operators
In order to allocate memory dynamically at run-time we use the new operator.
new returns a pointer that points to the beginning of a 'newly allocated block of memory'.
The general form for a single element is
and to assign a block (array) of elements
pointer = new type [number_of_elements];
For example, to request a 5 element block of type int dynamically, we can use
int * a;
a = new int [5];
or
The delete operator reverses the action of the new operator, that is
it frees the memory allocated by the new operator.
Its form is
delete pointer; // single element
delete [] pointer; // a block of elements
The program given below evaluates the mean of n-numbers where n is the input from keyboard.
02prg01.cpp: Simple use of a dynamic array
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
|
// Simple use of a dynamic array
#include <iostream>
using namespace std;
int main(){
double *x, mean, s;
int i, n;
// Repeat forever
while (true) {
// Get the number of elements
cout << "How many elements (zero to exit): ";
cin >> n;
// Check for n=0 and n<0
if (n==0) {
cout << "Bye." << endl << endl;
break;
}
else if (n<0) {
cout << "Negative number of elements?!" << endl;
continue;
}
// Request a memory location of a block of n doubles
x = new double[n];
// Get the elements and compute the sum
cout << "Input elements: ";
s = 0.0;
for(i=0; i<n; i++){
cin >> x[i];
s += x[i];
}
// Compute the mean
mean = s/n;
cout << "Mean = " << mean << endl << endl;
// Free the memory and continue the loop
delete [] x;
}
return 0;
} |
How many elements (zero to exit): 5
Input elements: 1 2 3 4 5
Mean = 3
How many elements (zero to exit): -2
Negative number of elements?!
How many elements (zero to exit): 6
Input elements: 1.1 2.7 4.4 -0.8 6.6 3.1
Mean = 2.85
How many elements (zero to exit): 0
Bye.
|
Note that the program continues to input new sets of data and outputs their mean.
On each repetition the data block is deleted (and the memory freed) and a new one created with the appropriate size.
This type of memory management can become important in cases where the number of elements is very large (and/or
the number of repetitions is very large),
for example if the data is being input from large data files. Omitting the delete statement
will cause memory usage to increase on each iteration (memory leak) thus causing the program to take more
memory resources from the computer than necessary. In the extreme case the operating system to run out of memory
or kill the program.
2.3 Dynamic Matrices
It is also possible to generate two or more dimensional dynamic arrays. In this case, pointers pointing to pointers are used.
General form to set up a two dimensional array is:
type pointer = new type [number_of_rows];
for(int i=0; i<number_of_columns; i++)
pointer = new type [i];
This allows you to access a dynamic matrix of the form:
type pointer[number_of_rows][number_of_columns];
The memory allocated for the pointer given above can be cleaned up as follows:
for(int i = 0; i < number_of_rows; i++)
delete[] pionter[i];
delete[] pointer;
An example usage is given below.
02prg02.cpp: Simple use of a dynamic matrix
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
|
// Simple use of a dynamic matrix
#include <iostream>
using namespace std;
int main(){
// Get the number of rows and columns
int nRow, nCol;
cout << "A Matrix Transposer (version 1.0)" << endl;
cout << "Input number of rows : ";
cin >> nRow;
cout << "Input number of columns: ";
cin >> nCol;
// Setup the matrix
int **matrix = new int * [nRow];
for (int i = 0; i < nRow; i++)
matrix[i] = new int [nCol];
// Get the elements (row wise)
cout << endl << "Input the elements of the matrix:" << endl;
for (int i = 0; i < nRow; i++)
for (int j = 0; j < nCol; j++)
cin >> matrix[i][j];
// Print out the transpose matrix
cout << endl << "Its transpose is:" << endl;
for (int i = 0; i < nCol; i++){
for (int j = 0; j < nRow; j++){
cout << matrix[j][i] << " ";
}
cout << endl;
}
// Cleanup the memory
for (int i = 0; i < nRow; i++){
delete[] matrix[i];
}
delete[] matrix;
return 0;
} |
A Matrix Transposer (version 1.0)
Input number of rows : 2
Input number of columns: 3
Input the elements of the matrix:
1 2 3
4 5 6
Its transpose is:
1 4
2 5
3 6
|
2.4 Dynamic Memory Management in ANSI-C
In the ANSI C language dynamic memory management can also be performed through the
malloc(), calloc(), realloc() and free()
functions which are available in C++ by including the <cstdlib> header file.
See: cplusplus.com/reference/clibrary/cstdlib
and also the Turkish-language web page: Dinamik Bellek Yönetimi.
2.5 Examples
02prg03.cpp: Getting sqrt of a dynamic array
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
|
// Getting sqrt of a dynamic array
#include <iostream>
#include <cmath>
using namespace std;
// Returns the sqrt of an array of given size
double *aSqrt(double *array, int size){
double *f = new double[size];
for(int k=0; k<size; k++)
f[k] = sqrt(array[k]);
return f;
}
// Prints the elements of vector v of given size
void printVector(double *v, int size){
for(int j=0; j<size; j++) cout << v[j] << " ";
cout << endl;
}
int main(){
int n;
cout << "Input the size: ";
cin >> n;
double *v = new double[n];
double *s = new double[n];
cout << "Input the elements: ";
for(int i=0; i<n; i++)
cin >> v[i];
s = aSqrt(v, n);
printVector(v, n);
printVector(s, n);
// clear the memory
delete [] v;
delete [] s;
return 0;
} |
Input the size: 4
Input the elements: 2 3 5 7
2 3 5 7
1.41421 1.73205 2.23607 2.64575
|
2.6 Exercises
- What is the action of the new operator?
- What is the action of the delete operator?
- What is wrong with the following code:
int *r = new [35];
- Write a program to find the mean, mode and median of an n-element integer dynamic array.
The median is the number in the middle and the mode is the most frequent number in a data set.
For example:
- For the data set {3, 4, 4, 5, 6, 8, 8, 8, 10}, median = 6 and mod = 8.
- For the data set {5, 5, 7, 9, 11, 11, 18, 18}, median = (9+11)/2 = 10 and mod = 18.
- Mode of the set: {2, 2, 5, 9, 9, 9, 10, 10, 11 12 18} is 9. (unimodal set of data)
Mode of the set: {2, 3, 4, 4, 4, 5, 7, 7, 7, 9} is 4 and 7 (bimodal set of data)
Mode of the set: {1, 2, 3, 8, 9, 10, 12, 14, 18} is ? (data has no mode)
- Write down the output of the following program:
#include <iostream>
int main(){
int m=3;
int *a = new int[m];
int *b = new int[m];
int d = 0.0;
for(int j=m-1; j>=0; j--) {
a[j] = j; b[j]=m-j;
std::cout << a[j] << " " << b[j] << std::endl;
d += a[j]*b[j];
}
delete [] a;
delete [] b;
std::cout << d << std::endl;
}
|