Note 4:
Dynamical Memory Management for Data Manipulation (Using Pointer)
The Concept of Pointer:
The computer stores variables in memory, and each memory location has a numeric address, in much the same way that each element of an array has its own subscript. Variable names in C++ and other high-level languages enable the programmer to refer to memory locations by name, but the compiler must translate these names into addresses. This process is automatic, so we need not concern ourselves with it. Moreover, many program problems require that the programmer be able to refer to those addresses indirectly in order to manipulate the contents of the corresponding memory location. In a sense, the address or name of a memory location points to whatever that memory location contains.
Pointer:
It is a variable that can store a memory address. The type of item pointed to by a pointer variable is the target type.
Declarations:
An address is a separate data type in C++. The address of an int variable is of a type distinctly different from that of a char variable. We declare a variable, ptr, which can hold the address of an integer as follows:
short *ptr;
The asterisk is not part of the variable name. Rather, short * (read ※pointer to short§) is the type of variable ptr.
Address Operator:
The pointer does not point to anything initially. To assign an address to a pointer, the programmer must assign it a value. An ampersand (&) immediately preceding a variable name, such as V, returns the address of the variable. Thus, execution of the statement
Ptr = &V;
Assigns the address of V to ptr. This ampersand or address operator applied to a variable of type int returns a constant value of type int *, which we can assign to a variable of type int *. We can use the & operator with a value, such as a variable name or an array element, but it can never precede a constant, an expression (other than a scalar variable), or the unsubscripted name of an array.
Initialize pointer:
To have ptr no longer store the address of V, we can assign a special constant, NULL. To ptr, as follows:
Ptr = NULL;
Two things you should remember about pointer are
Summary of meaning of code for declaration-initializations short V = 5, *ptr = &V
Code |
Meaning |
Picture |
&ptr |
address of variable ptr |
|
ptr |
value of ptr ; contents of memory location for ptr ; address of V |
|
&V |
address of variable V |
|
*ptr |
dereferenced value of ptr; contents of location to which ptr points ; value of V |
|
V |
value of V ; contents of memory location for V |
|
Dynamic Allocation of Memory:
For use and representation of 1 to n dimension array
short *arraynd = new short[24];
Single Dimension Array:
Two Dimension Array:
Three Dimension Array:
Dynamically allocated block of memory containing information about representation for a 1-3 dimensional array.
short *arraynd = new short[28];
arraynd += 4;
The number of dimensions represented by the block of memory would determine the number of elements to the left of element 0. If the block of memory represented a single dimension array then only 1 element would be needed to the left of element 0 to contain the number of element in the array. If the block of memory represented only different size two dimension arrays then only two elements to the left of element zero would be need to contain the number of rows and columns for the array.
Two dimension array example:
Accessing data in array table:
Type Dimension |
Compile time |
Dynamical |
Note |
One |
ArrayName[N] |
*(PtrName+N) |
N is element of array |
Two |
ArrayName[r][c] *(ArrayName[r]+c) *(*(ArrayName+r)+c) |
*(PtrName+r*col_size+c) |
r is row subscript c is column subscript |
Three |
ArrayName[p][r][c] *(ArrayName[p][r]+c) *(*(ArrayName[p]+r)+c) *(*(*(ArrayName+p)+r)+c) |
*(PtrName+p*col_size*row_size+r*col_size+c) |
p is page subscript r is row subscript c is column subscript |
Free the Memory:
As a good programmer, you should free the memory that you allocated for the program to use when you do not need it. After you allocated the memory for the pointer, you should keep track the pointer. When you want to free the memory, you have to move the pointer back to original location to be able to delete the pointer for free the memory.
short *ptr;
ptr = new short [n]; // Allocated memory for short pointer variable ptr
:
delete [] ptr; // Free the memory that allocated to ptr
Matrix Transposition:
Transposes while coping to another block of memory
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Source Code:
// Function definition to transpose a block of memory manipulated as a matrix with any
// number of rows and columns into another block of memory also manipulated as a
// matrix.
void matrix_transpose (int *fnum1, int *fnum2, int rows_num1, int cols_num1,
int &rows_num2, int &cols_num2)
{
short i, j, *start_fnum1;
rows_num2 = cols_num1; // assign number of rows to fnum2
cols_num2 = rows_num1; // assign number of columns to fnum2
for (j = 0; j < cols_num1; j ++)
{
start_fnum1 = fnum1 + j; // set pointer to beginning of column j in fnum1
for (i = 0; I < rows_num1; I ++)
{
*fnum2 ++ = *start_fnum1; // copy values from fnum1 to fnum2
// and increment pointer to next
// element of fnum2
start_fnum1 += cols_num1; // advance pointer to next row in same
// column
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Row Major and Column Major of a Matrix:
Graphical Representation of a matrix for both Row Major and Column Major Storage Models:
Memory Representation of Row Major:
Memory Representation Column Major:
Function to convert between Storage Models:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Source Code:
void convert_storage_model(short *from_model, short *to_model, short rows,
short columns, short from_model_flag,
short to_model_flag)
{
short *temp_ptr, i, j;
if(from_model_flag) // from_model is row major, data will be stored in column major
{
to_model_flag = 0;
for(i=0; i<rows; i++)
{
temp_ptr = to_model++; // set temp_ptr to next row (next element in
// column major order)
for (j = 0; j<columns; j++)
{
*temp_ptr = *from_model++; // copy values from consecutive
// elements in from_model to
//to_model
temp_ptr += rows; // increment temp_ptr to next column
}
}
else // from_model is column major, data will be stored in row major
{
to_model_flag = 1;
for(j=0; j<cols; j++)
{
temp_ptr = to_model++; // set temp_ptr to next column (next element in
// row major order)
for(i=0; i<rows; i++)
{
*temp_ptr = *from_model++; // copy values from consecutive
// elements in from_model to
// to_model
temp_ptr += columns; // increment temp_ptr to next row
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Grouping Multiple Structures by Using Pointer Array:
Grouping multiple structures by using pointer Array is an unusual structure. It point to several structures, which could include any dimension arrays, stack, queue, link list#etc.
Example:
A pointer array has been created to point to several 1, 2, 3 dimension arrays. See the diagram above. The structure, which was dynamically allocated, is an array of pointers to type short. The address of this structure has been assigned to a variable that is a pointer to pointer. Element zero of this structure points to an integer location that contains a value that is the number of arrays (include 1, 2, 3 dimension) to which the array of pointers point. Each array has been dynamically allocated so that array contains proper information such as the number of pages, rows, and columns of data in the array in addition to the data that has been stored in the array. The pointer to the array points to the element 0 of the array using manipulated the data in that array.
Allocated the Memory for Each Array:
short* ptr_array[n]; // Array of pointer
ptr_array[1] = new short [R * C + 2]; //Allocated the memory for array 1
Initialized the array1:
ptr_array[1] = ptr_array[1] + 2; // Moved the pointer to point at element 0 of array 1
*(ptr_array[1] 每 1) = C; // Stored the column size information in the array 1
*(ptr_array[1] 每 2) = R; // Stored the row size information in the array 1
Access Data in the Array:
Two ways:
1. Direct access the data of array from the pointer array
// Access the data of array 1, i = 1
*( *(ptr_array + i) + row_subscript * (*(ptr_array + i ) 每 1) + column_subscript);
or
*(ptr_array[i] + row_subscript * (*(ptr_array[i] 每 1)) + column_subscript);
2. Indirect access the data of array
// Access the data of array 1, i = 1
ptr = *(ptr_array + i); // Copy the address of the array 1 to ptr
*(ptr + row_subscript * (*(ptr 每1)) + column_subscript);
Free the Memory for Each Array:
1. Move the pointer back to the original position.
2. Then using the loop to delete the pointers in the array of pointer.
for (i = 0; i < n; i ++)
{
delete [] ptr_array[i];
}