Question #1
Write down the output of the following program segment. Getting the first,
second and third output lines correct are worth 6, 7 and 7 marks respectively.
You may use the next page as well. Hint: to receive partial marks, in
case you get the output wrong, you probably want to indicate what the four
pointers are pointing to after each line.
int a = 1, b = 2, c = 3,
*p1, *p2,
**pp1, **pp2;
p1 = &b;
p2 = &c;
pp1 = &p1;
pp2 = &p2;
if (**pp2 == *p1 + a) {
cout << "TRUE" << endl;
} else {
cout << "FALSE" << endl;
}
**pp1 = *p2 + c;
*pp2 = p1;
*p2 = *p1 + a;
cout << "FIRST: " << a << ' ' << b << ' ' << c << endl;
*pp1 = &a;
p1 = *pp1;
**pp2 = **pp1 + *p1;
cout << "SECOND: " << a << ' ' << b << ' ' << c << endl;
| Assgn. |
a |
b |
c |
p1 |
p2 |
pp1 |
pp2 |
*pp1 |
*pp2 |
| p1 = &b |
1 |
2 |
3 |
&b |
? |
? |
? |
? |
? |
| p2 = &c |
. |
. |
. |
. |
&c |
? |
? |
? |
? |
| pp1 = &p1 |
. |
. |
. |
. |
. |
&p1 |
? |
p1 |
? |
| pp2 = &p2 |
. |
. |
. |
. |
. |
. |
&p2 |
. |
p2 |
| **pp1 = *p2 + c |
. |
6 |
. |
. |
. |
. |
. |
. |
. |
| *pp2 = p1 |
. |
. |
. |
. |
&b |
. |
. |
. |
. |
| *p2 = *p1 + a |
. |
7 |
. |
. |
. |
. |
. |
. |
. |
| *pp1 = &a |
. |
. |
. |
&a |
. |
. |
. |
. |
. |
| p1 = *pp1 |
. |
. |
. |
. |
. |
. |
. |
. |
. |
| **pp2 = **pp1 + *p1 |
. |
2 |
. |
. |
. |
. |
. |
. |
. |
HENCE, the output is:
TRUE
FIRST: 1 7 3
SECOND: 1 2 3
Question #2
Dynamic Memory Allocation & Arrays
The diagram above is the
layout of a two dimensional structure. The symbolic identifier a of
type int** has the address 0x1002. All pointers are 32 bit and
the integers are 16 bit long. Answer the 3 questions below, starting on the next
page.
Given the variable declaration
int ** a;
write a short code segment ( no need for functions, loops or program, only
the relevant lines), which allocates the very same structure as on the
previous page. You do not have to initialize the array elements to the values
on the diagram! The addresses indicate how the structure is allocated, and
of course, you may assume that the addresses returned by the new or new[]
operators in the sequence you call them are the same as on the diagram. Hint:
you do not need more than 4 lines.
a = new int*[3]; // the array of int*'s staring at 0x2007
a[0] = new int[5]; // the array of int's starting at 0x3002
a[1] = new int[3]; // the array of int's starting at 0x1009
a[2] = a[0];
Write a short code segment which deallocates the structure. Hint: you
can do it in three lines.
delete [] a[0];
delete [] a[1];
delete [] a;
Assuming that the addresses and values are exactly as they are on the diagram,
and after executing the following few lines of code
a[0][2] = 7;
a[1][1] = -6;
write down the values of the following expressions:
a[1] = 0x1009
a[2][2] = 7
**a = 90
a = 0x2007
Question #3
The following three short program segments each have at least one
problem. You are to find one in each and give a sentence or so
explanation describing what exactly the problem is. Hint: there are no
syntax errors!
Find an error, and describe it.
void foo(double* ptr,double v) {
if (ptr == (double*)0) {
ptr = new double;
// ptr is a pointer on the stack,
// which is assigned a new address
// at that point, it is out of sync
// with the parameter passed (namely y)
// and causes a memory leak
// This situation is described in detail on pp. 40
}
*ptr = 2*v;
}
double x, *y = (double*)0;
foo(y,x);
Find an error, and describe it.
int* foo(int *a, int *b) {
int c = *a + *b,
d = *a - *b;
a = c > d ? &c : &d;
// regardless, whether c > d or c <= d
// the pointer variable a is assigned
// either address &c or &d, both local
// variables. Returning the address of
// a local variable is a serious mistake
// pp 42 in your notes
return a;
}
Find an error, and describe it.
int x; // x is global, OK
int& func(bool b) {
if (b) x++;
else x--;
return x; // x is not local, OK
}
int* foo(int& (*f) (bool), bool v) {
int x = f(v); // x is a LOCAL variable
return &x;
// returning the address of a local variable
// is serious mistake! pp 42 on your notes
}
int main() {
*(foo(func,5>2)) = 7; // dereferencing the local variable!
return 0;
}
Question #4
Consider the following class definition, method and function implementations :
class C {
public:
C();
C(int);
C(const C&);
C& operator=(const C&);
~C();
};
C foo(C c) {
return c;
}
C::C() { cout << "C::C()" << endl; }
C::C(int) { cout << "C::C(int)" << endl; }
C::C(const C&) { cout << "C::C(const C&)" << endl; }
C& C::operator=(const C&) { cout << "C::operator=" << endl; return *this; }
C::~C() { cout << "C::~C()" << endl; }
Answer the question posed on the following page.
Give the output of the following short code segment, and explain briefly but
clearly what caused each line to be printed! Hint: the two lines
are in a local scope!
...
{
C c[2];
c[1] = 34;
}
...
C::C() - for c[0]
C::C() - for c[1]
C::C(int) - 34 is of type int not C
however it has a constructor
which can create a C from an int
hence a temporary instance is created
C::operator= - for the assignment
C::~C() - on the temporary instance
C::~C() - for c[1], scope ends
C::~C() - for c[0], scope ends
Question #5
Write a program with one function. The function takes an integer array
and its length, and reverses the order of the elements. Call this function once
in main to perform this task on an array that you declared and
initialized.
#include < iostream.h >
void rev(int *a, int l) {
for(int i=0; i < l/2 ; i++) {
int tmp = a[i];
a[i] = a[l-i-1];
a[l-i-1] = tmp;
}
}
int main() {
int a[5] = {1,2,3,4,5};
cout << a[0] << ',' << a[1] << ',' << a[2] << ',' << a[3]
<< ',' << a[4] << endl;
rev(a,5);
cout << a[0] << ',' << a[1] << ',' << a[2] << ',' << a[3]
<< ',' << a[4] << endl;
return 0;
}