0% found this document useful (0 votes)
13 views39 pages

NU-Lec 2 - Dynamic Memory Allocation

Uploaded by

badarfatima43
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views39 pages

NU-Lec 2 - Dynamic Memory Allocation

Uploaded by

badarfatima43
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 39

Object Oriented Programming

Lecture No. 2
Accessing Arrays
and
Dynamic Memory Allocation (DMA)
Relationship Between Pointers and Arrays
• Arrays and pointers are closely related
– Array name is like constant pointer
– All arrays elements are placed in the consecutive
locations. (This is only valid in static memory
allocation)
• Example:- int List [10];

– Pointers can do array subscripting operations (We can


access array elements using pointers).
• Example:- int *ptr = List;
Relationship Between Pointers and Arrays (Cont.)

• Accessing array elements with pointers


– Assume declarations:
int List[ 5 ];
int *bPtr;
bPtr = List;
Effect:-
- List is an address, no need for &
- The bPtr pointer will contain the address of the first element of
array List.
– Element List[ 2 ] can be accessed by *( bPtr + 2 )
Accessing 1-Demensional Array Using Pointers
Address Data
• We know, Array name denotes the memory address Element 0
980
of its first slot.
982 Element 1
– Example:
984 Element 2
• int List [ 50 ];
986 Element 3
• int *Pointer;
• Pointer = List; 988 Element 4

• Other slots of the Array (List [50]) can be accessed 990 Element 5

using by performing Arithmetic operations on 992 Element 6


Pointer. 994 Element 7
• For example the address of (element 4th) can be 996 Element 8
accessed using:- …
– int *Value = Pointer + 3;

• The value of (element 4th) can be accessed using:-
– int Value = *(Pointer + 3); 998 Element 50
Accessing 1-Demensional Array

Address Data
int List [ 50 ]; 980 Element 0
982 Element 1
int *Pointer;
984 Element 2
Pointer = List; // Address of first Element 986 Element 3
293
988 Element 4
990 Element 5
int *ptr; 992 Element 6
994 Element 7
ptr = Pointer + 3; // Address of 4th Element
996 Element 8
*ptr = 293; // 293 value store at 4th element …
address

998 Element 50
Accessing 1-Demensional Array
We can access all element of List [50] using
Pointers and for loop combinations. Address Data
int List [ 50 ]; 980 Element 0
982 Element 1
int *Pointer; Element 2
984
Pointer = List; 986 Element 3
988 Element 4
for ( int i = 0; i < 50; i++ )
990 Element 5
{ 992 Element 6
cout << *Pointer; 994 Element 7
996 Element 8
Pointer++; // Address of next element

} …
This is Equivalent to 998 Element 50

for ( int loop = 0; loop < 50; loop++ )


cout << Array [ loop ] ;
Accessing 2-Demensional Array
• In 2-Demensional array the statements
– int List [ 5 ] [ 6 ];
– int *Pointer;
– Pointer = List [3];
• Represents that we are accessing the address of 4th row

• or the address the 4th row and 1st column.


Accessing 2-Demensional Array
– int List [ 9 ] [ 6 ]; Column

– int *ptr; 0 1 2 3 4 5

– ptr = List [3]; 0 300 302 304 306 308 310


1 312 314 316 318 320 322
• To access the address of 4th row 2 324 326 328 330 332 334

2nd column we can increment 3 336 338 340 342 344 346

Row
4 348 350 352 354 356 358
the value of (ptr). 5 360 362 364 366 368 370

– ptr++; // address of 4th row 2nd 6 372 374 376 378 380 382
7 384 386 388 390 392 394
column
8 396 398 400 402 404 406
– Equivalent to List [3][1] ;

Memory address
Accessing 2-Demensional Array
• We know computer can perform only one
Column
operation at any time (remember fetch-
decode-execute cycle). 0 1 2 3 4 5

0 300 302 304 306 308 310


• Thus to access List [3][1] element (without
1 312 314 316 318 320 322
pointer) two operations are involved:-
– First to determine row List [3] 2 324 326 328 330 332 334
– Second to determine column List[3][1] 3 336 338 340 342 344 346

Row
4 348 350 352 354 356 358
5 360 362 364 366 368 370
• But using pointer we can reach the element of 6 372 374 376 378 380 382
4th row 2nd column (directly) by increment our
7 384 386 388 390 392 394
pointer value (which is a single operation).
– ptr++; // 4th row 2nd column 8 396 398 400 402 404 406
– ptr+1; // 4th row 3rd column
– ptr+2; // 4th row 4th column

Memory address
Dynamic Memory Allocation
• Static Memory Allocation (SMA):-
• Used when space requirements are unknown at compile time.
• Most of the time the amount of space required is unknown at
compile time.
– For example consider the library database example having 200 data
set declared, what about 201th book information?

• Dynamic Memory Allocation (DMA):-


– With Dynamic memory allocation we can allocate/deletes memory
(elements of an array) at runtime or execution time.
Differences between Static and Dynamic
Memory Allocation
• Dynamically allocated memory is kept on the
memory heap (also known as the free store)
• Dynamically allocated memory can't have a
"name", it must be referred to

• Declarations are used to statically allocate


memory, the new operator is used to dynamically
allocate memory
Pointing to Memory Allocated at Run Time
• int *ptr;
• ptr = new int;
• *ptr = 7;
• int *a;

• a = new int[3];
– *a = 300;
– *(a+1) = 301;
– *(a+2) = 302;
Returning Memory to the Heap
• How Big is the Heap?
– Most applications request memory from the heap when
they are running
– It is possible to run out of memory (you may even have
gotten a message like "Running Low On Virtual
Memory")
– So, it is important to return memory to the heap when
you no longer need it
Another example
• Suppose you have the following declaration:
int *p;
This statement declares p to be a pointer variable
of type int. Next, consider the
following statements:
p = new int; //Line 1
*p = 54; //Line 2
p = new int; //Line 3
*p = 73;
Another example
Returning Memory to the Heap
• The Opposite of new:
– In C++: The delete operator in C++
• delete ptr;
Dangling Pointers
• The delete operator does not delete the pointer, it takes the
memory being pointed to and returns it to the heap

• It does not even change the contents of the pointer

• Since the memory being pointed to is no longer available


(and may even be given to another application), such a
pointer is said to be dangling
• ptr = NULL;
Returning Memory to the Heap

• Remember:
– Return memory to the heap before undangling the pointer

• e.g.
• delete ptr;
• Ptr=NULL;
Returning Memory to the Heap
• For Arrays
– delete[ ] a;
– a = NULL;
Memory Leaks
• Memory leaks when it is allocated from the heap
using the new operator but not returned to the
heap using the delete operator
• int *otherptr;
• otherptr = new int;

• *otherptr = 4;
• otherptr = new int;
Casting pointers (1/2)

 Pointers have types, so you can’t just do

int *pi; double *pd;


pd = pi;
Casting pointers (2/2)

 C++ will let you change the type of a pointer with


an explicit cast

int *pi; double *pd;


pd = (double*) pi;
Void Pointers
 float flovar = 98.6;
 int* ptrint = &flovar; //ERROR: can’t assign float* to

int*
 However, there is an exception to this. There is a

sort of general-purpose pointer that can point to


any data type. This is called a pointer to void, and is
defined like this:
 void* ptr; //ptr can point to any data type
Limitations
• the data pointed to by them cannot be directly
dereferenced (which is logical, since we have no
type to dereference to)
• and for that reason, any address in a void pointer
needs to be transformed into some other pointer
type that points to a concrete data type before
being dereferenced.
Casting
• ptrint = reinterpret_cast<int*>(flovar);
• ptrflo = reinterpret_cast<float*>(intvar);
Functions
• What is a function?
• How many ways to pass arguments to a function?
Calling Functions
• 3 ways to pass arguments to function
– Pass-by-value
– Pass-by-reference with reference arguments
– Pass-by-reference with pointer arguments
• Arguments passed to function using values
– Already done in detail
• Arguments passed to function using reference
arguments
– Modify original values of arguments
– More than one value “returned”
Calling Functions
• Pass-by-reference with pointer arguments
– Simulate pass-by-reference
• Use pointers and indirection operator
– Pass address of argument using & operator
– Arrays not passed with & because array name already
pointer
– * operator used as alias/nickname for variable inside of
function
32
1 // code 2
2 // Cube a variable using pass-by-value.
3 #include <iostream>
4
5 using std::cout;
6 using std::endl;
7
8 int cubeByValue( int ); // prototype
9
10 int main()
11 {
12 int number = 5;
13
14 Pass
cout << "The original value of number is " << number by value;
number; result
15 returned by
16 // pass number by value to cubeByValue cubeByValue
17 number = cubeByValue( number );
18
19 cout << "\nThe new value of number is " << number << endl;
20
21 return 0; // indicates successful termination
22
23 } // end main
24
33
25 // calculate and return cube of integer argument
26 int cubeByValue( int n )
27 {
28 cubeByValue
return n * n * n; // cube local variable receives
n and return result
29 parameter passed-by-value
30 } // end function cubeByValue

The original value of number is 5


Cubes and returns
The new value of number is 125 local variable n
34
1 // code 2
2 // Cube a variable using pass-by-reference
3
4 #include <iostream>
5
Prototype indicates parameter
6 using std::cout;
7 using std::endl;
is pointer to int
8
9 void cubeByReference( int & ); // prototype
10
11 int main()
12 {
13 int number = 5;
14
15 cout << "The original value of number is " << number;
16
17 // pass number to cubeByReference
18 cubeByReference( number );
19
20 cout << "\nThe new value of number is " << number << endl;
21
22 return 0; // indicates successful termination
cubeByReference
23
modified variable
24 } // end main
25
number
35
26 // calculate cube modifies variable number in main
27 void cubeByReference( int &num )
28 {
29 num = num * num * num;
30
cubeByReference
31 } // end function cubeByReference receives address of int
variable,
The original value of number is 5
The new value of number is 125
36
1 // code 3
2 // Cube a variable using pass-by-reference
3 // with a pointer argument.
4 #include <iostream>
5
Prototype indicates parameter
6 using std::cout;
7 using std::endl;
is pointer to int
8
9 void cubeByReference( int * ); // prototype
10
11 int main()
12 {
13 int number = 5;
14
Apply address operator & to
15 cout << "The original value of number is " << number;
pass address of number to
16
17
cubeByReference
// pass address of number to cubeByReference
18 cubeByReference( &number );
19
20 cout << "\nThe new value of number is " << number << endl;
21
22 return 0; // indicates successful termination
cubeByReference
23
modified variable
24 } // end main
25
number
37
26 // calculate cube of *nPtr; modifies variable number in main
27 void cubeByReference( int *nPtr )
28 {
29 *nPtr = *nPtr * *nPtr * *nPtr; // cube *nPtr
30
cubeByReference
31 } // end function cubeByReference receives address of int
variable,
The original value of number is 5
i.e., pointer to an int
The new value of number is 125
Modify and access int
variable using indirection
operator *
Dynamic two dimensional arrays

Pointer to Pointer

and
What's Wrong with the Following:
ptr = NULL;
delete ptr;

(Search and Answer)


References
• Part of lecture slides based on slides from
– Prof. David Bernstein
James Madison University

You might also like