Beruflich Dokumente
Kultur Dokumente
Lecture No. 18
___________________________________________________________________
Data Structures
Lecture No. 18
Reading Material
Data Structures and Algorithm Analysis in C++
Chapter. 4
4.3.3
Summary
Reference Variables
const keyword
Tips
Reference Variables
In the last lecture we were discussing about reference variables, we saw three examples;
call by value, call by reference and call by pointer. We saw the use of stack when a
function is called by value, by reference or by pointer. The arguments passed to the
function and local variables are pushed on to the stack.
There is one important point to note that in this course, we are using C/C++ but the usage
of stack is similar in most of the computer languages like FORTRAN and Java . The
syntax we are using here is C++ specific, like we are sending a parameter by pointer
using & sign. In Java, the native data types like int, float are passed by value and the
objects are passed by reference. In FORTRAN, every parameter is passed by reference. In
PASCAL, you can pass a parameter by value or by reference like C++. You might have
heard of ALGOL, this language had provided another way of passing parameter called
call by name. These kinds of topics are covered in subjects like Study of Computer
Languages or Compilers Theory.
It is recommended while you are doing your degree, you study other computer languages
and compare them from different aspects. Java is quite popular now a day, quite similar in
syntax to C++. May be as a next language, you can study that and compare its different
aspects with C/C++. The concepts like how a program is loaded into memory to become
a process, how the functions are called and the role of stack etc are similar in all major
languages.
we have discussed when the variables are passed by reference then behind the scene what
goes on inside the stack. There are few important things to take care of while using
reference variables:
One should be careful about transient objects that are stored by reference in data
structures.
We know that the local variables of a function are created on call stack. Those variables
Page 1 of 8
Process 1
(Browser)
Code
Process 3
(Word)
Static Data
Process 4
(Excel)
Stack
Process 2
(Dev-C++)
Windows OS
Heap
One the left of the picture, we can see different processes in the computer memory. When
we zoomed into the one of the processes, we saw the picture on the right. That firstly,
there is a section for code, then for static data and for stack. Stack grows in the
downward section. You can see the heap section given at the end, which grows upward.
An interesting question arises here is that why the stack grows downward and heap in the
upward direction. Think about an endless recursive call of a function to itself. For every
invocation, there will be an activation record on stack. So the stack keeps on growing and
growing even it overwrites the heap section. One the other hand, if your program is
performing dynamic memory allocation endlessly, the heap grows in the upward direction
such that it overwrites the stack section and destroys it.
You might have already understood the idea that if a process has some destructive code
then it will not harm any other process, only its own destruction is caused. By the way, lot
of viruses exploit the stack overflow to change the memory contents and cause further
destruction to the system.
Consider that we allocate an array of 100 elements of Customer objects dynamically. As
each object is 44 bytes, therefore, the size of memory allocated on heap will be 4400
bytes (44 * 100). To explain the allocation mechanism on stack and heap, lets see the
Page 4 of 8
688
c2
sohail
Customer(sohail) -> c2
644
irfan
Customer(irfan) -> c1
600
Page 5 of 8
1072
600
1068
644
1060
.
.
.
.
(644)
c1
c2
loadCustomer
(elt)
1056
1052
enqueue
sp
stack grows downwards
Fig 18.3: Stack layout when q.enqueue(2) called from loadCustomer
The loadCustomer() is being executed. It is containing two pointers c1 and c2 containing
the addresses 600 and 643 respectively. enqueue(elt) method is called and the parameter
values (which actually are addresses) 600 and 643 are inserted in the queue.
Because the objects have been allocated on heap, therefore, there will no issue with them.
The pointer variables c1 and c2, which we used to store addresses, are destroyed. But the
queue q, which is passed by reference to loadCustomer will be there and it is containing
the starting addresses of the Customer objects. Those are valid addresses of valid objects,
so they can used in the program later to access the customer objects. See the function
below:
void serviceCustomer( Queue & q)
{
Customer* c = q.dequeue();
cout << c->getName() << endl;
delete c; // the object in heap dies
}
You can see that we are taking one pointer out of the queue and in the second line calling
Page 6 of 8
The function movePiece() above is passed one parameter, which is passed by reference.
By writing const, we are saying that parameter must remain constant for the life of the
function. If we try to change value, for example, the parameter appears on the left side of
the assignment, the compiler will generate an error. This also means that if the parameter
is passed to another function, that function must not change it either.
Use of const with reference parameters is very common. This is puzzling; why are we
passing something by reference and then make it constant, i.e., dont change it? Doesnt
passing by reference mean we want to change it?
Think about it, consult your C++ book and from the internet. We will discuss about the
answer in the next lecture.
Page 7 of 8
Tips
Page 8 of 8