aliasing
DESCRIPTION
Aliasing. Joe Meehean. Aliasing. An alias is another name for the same object two variables names are attached to the same data Aliasing is really important in C++ and many other programming languages well see why when we cover Objects C++ does aliasing in two ways references pointers. - PowerPoint PPT PresentationTRANSCRIPT
Aliasing
Joe Meehean
Aliasing• An alias is another name for the same object• two variables names are attached to the same data
• Aliasing is really important in C++• and many other programming languages• well see why when we cover Objects
• C++ does aliasing in two ways• references• pointers
2
References• References are aliases that “refer” to other variables• its just another name for an object
• Compound type• type defined in terms of another type• e.g., arrays are compound types
• Reference is a compound type• type &variable;• e.g., int &foo;• should be read from right to left:
“foo is a reference to an int”
3
References• Initializing a reference• References must be initialized at declaration• Must be initialized using object of the same type• cannot be initialized using a literal
• After initialization a reference is forever bound to that object• cannot rebind to another object
4
int val = 7;int &refVal = val; // GOODint &refVal2; // ERRORint &refVal3 = 11; // ERRORdouble dval = 2.1;int &refVal3 = dval; // ERROR
References• All operations on a reference are performed on the
underlying object
5
int val = 7;int &refVal = val;
7val
refVal
refVal = 9; 9val
refVal
val++; 10val
refVal
References• References to constants• cannot change the underlying data• can refer to a const object or even literals• created using const keyword
6
const int val = 7;const int &refVal = val; // GOOD
int &refVal2 = val; // ERROR
const int &refVal3 = 11; // GOOD
const int &refVal4 = 12 * 57 + 1; // GOOD
References• As parameters of a function• nonreference parameters are copied using the
corresponding function arguments• the original arguments cannot be changed
7
int arg1 = 7;int arg2 = 15;swap(arg1, arg2);
void swap(int parm1, int parm2){ int tmp = parm1; parm1 = parm2; parm2 = tmp;}
7arg1
15arg2
References• As parameters of a function• nonreference parameters are copied using the
corresponding function arguments• the original arguments cannot be changed
8
int arg1 = 7;int arg2 = 15;swap(arg1, arg2);
void swap(int parm1, int parm2){ int tmp = parm1; parm1 = parm2; parm2 = tmp;}
7arg1
15arg2
7parm1
15parm2
References• As parameters of a function• nonreference parameters are copied using the
corresponding function arguments• the original arguments cannot be changed
9
int arg1 = 7;int arg2 = 15;swap(arg1, arg2);
void swap(int parm1, int parm2){ int tmp = parm1; parm1 = parm2; parm2 = tmp;}
7arg1
15arg2
7 15parm1
15 7parm2
References• As parameters of a function• nonreference parameters are copied using the
corresponding function arguments• the original arguments cannot be changed
10
int arg1 = 7;int arg2 = 15;swap(arg1, arg2);
void swap(int parm1, int parm2){ int tmp = parm1; parm1 = parm2; parm2 = tmp;}
7arg1
15arg2
References• As parameters of a function• reference parameters only copy the reference,
not the actual data• binds parameters to argument’s data
11
int arg1 = 7;int arg2 = 15;swap(arg1, arg2);
void swap(int& parm1,int& parm2){ int tmp = parm1; parm1 = parm2; parm2 = tmp;}
7arg1
15arg2
References• As parameters of a function• reference parameters only copy the reference,
not the actual data• binds parameters to argument’s data
12
int arg1 = 7;int arg2 = 15;swap(arg1, arg2);
void swap(int& parm1,int& parm2){ int tmp = parm1; parm1 = parm2; parm2 = tmp;}
7arg1
15arg2
parm2
parm1
References• As parameters of a function• reference parameters only copy the reference,
not the actual data• binds parameters to argument’s data
13
int arg1 = 7;int arg2 = 15;swap(arg1, arg2);
void swap(int& parm1,int& parm2){ int tmp = parm1; parm1 = parm2; parm2 = tmp;}
7 15arg1
15 7arg2
parm2
parm1
References• As parameters of a function• reference parameters only copy the reference,
not the actual data• binds parameters to argument’s data
14
int arg1 = 7;int arg2 = 15;swap(arg1, arg2);
void swap(int& parm1,int& parm2){ int tmp = parm1; parm1 = parm2; parm2 = tmp;}
7 15arg1
15 7arg2
References• Passing references avoids expensive copies• Adds new problems that data may be changed• maybe we want to be sure it won’t be• or want to use literals without copying
• Pass const references
15
bool isNegative(int& parm1){ return (parm1 < 0 );}
int val = -7;isNegative(val); // OKisNegative(-15); // WON’T COMPILE
References• Passing references avoids expensive copies• Adds new problems that data may be changed• maybe we want to be sure it won’t be• or want to use literals without copying
• Pass const references
16
bool isNegative(const int& parm1){ return (parm1 < 0 );}
int val = -7;isNegative(val); // OKisNegative(-15); // OK
References• Returning nonreferences• the return value (object) is copied• e.g., add 1 to absolute value
17
int arg = -4;abs(arg)++;cout << arg << endl;
int abs(int& parm){ if( parm < 0 ){ parm = parm * -1; } return parm;}
-4arg
References• Returning nonreferences• the return value (object) is copied• e.g., add 1 to absolute value
18
-4arg
parm
int arg = -4;abs(arg)++;cout << arg << endl;
int abs(int& parm){ if( parm < 0 ){ parm = parm * -1; } return parm;}
References• Returning nonreferences• the return value (object) is copied• e.g., add 1 to absolute value
19
-4 4arg
parm
int arg = -4;abs(arg)++;cout << arg << endl;
int abs(int& parm){ if( parm < 0 ){ parm = parm * -1; } return parm;}
References• Returning nonreferences• the return value (object) is copied• e.g., add 1 to absolute value
20
-4 4arg
4tmp
int arg = -4;abs(arg)++;cout << arg << endl;
int abs(int& parm){ if( parm < 0 ){ parm = parm * -1; } return parm;}
References• Returning nonreferences• the return value (object) is copied• e.g., add 1 to absolute value
21
-4 4arg
4 5tmp
int arg = -4;abs(arg)++;cout << arg << endl;
int abs(int& parm){ if( parm < 0 ){ parm = parm * -1; } return parm;}
References• Returning nonreferences• the return value (object) is copied• e.g., add 1 to absolute value
22
4argint arg = -4;abs(arg)++;cout << arg << endl;
int abs(int& parm){ if( parm < 0 ){ parm = parm * -1; } return parm;}
References• Returning a reference• the object itself is returned• returned reference can be assigned new data or updated
23
int arg = -4;abs(arg)++;cout << arg << endl;
int& abs(int& parm){ if( parm < 0 ){ parm = parm * -1; } return parm;}
-4arg
parm
References• Returning a reference• the object itself is returned• returned reference can be assigned new data or updated
24
int arg = -4;abs(arg)++;cout << arg << endl;
int& abs(int& parm){ if( parm < 0 ){ parm = parm * -1; } return parm;}
arg
parm
-4 4
References• Returning a reference• the object itself is returned• returned reference can be assigned new data or updated
25
int arg = -4;abs(arg)++;cout << arg << endl;
int& abs(int& parm){ if( parm < 0 ){ parm = parm * -1; } return parm;}
-4 4arg
tmp
References• Returning a reference• the object itself is returned• returned reference can be assigned new data or updated
26
int arg = -4;abs(arg)++;cout << arg << endl;
int& abs(int& parm){ if( parm < 0 ){ parm = parm * -1; } return parm;}
4 5arg
tmp
References• Returning a reference• the object itself is returned• returned reference can be assigned new data or updated
27
int arg = -4;abs(arg)++;cout << arg << endl;
int& abs(int& parm){ if( parm < 0 ){ parm = parm * -1; } return parm;}
5arg
References• Returning a reference• never return a reference a local object
28
int arg1 = 2;int arg2 = 5;int sum = add(arg1, arg2);
int& add( int& parm1, int& parm2){ int val = parm1 + parm2; return val;}
2arg1
5arg2
References• Returning a reference• never return a reference a local object
29
int arg1 = 2;int arg2 = 5;int sum = add(arg1, arg2);
int& add( int& parm1, int& parm2){ int val = parm1 + parm2; return val;}
2arg1
5arg2
parm2
parm1
References• Returning a reference• never return a reference a local object
30
int arg1 = 2;int arg2 = 5;int sum = add(arg1, arg2);
int& add( int& parm1, int& parm2){ int val = parm1 + parm2; return val;}
2arg1
5arg2
parm2
parm2
7val
References• Returning a reference• never return a reference a local object
31
int arg1 = 2;int arg2 = 5;int sum = add(arg1, arg2);
int& add( int& parm1, int& parm2){ int val = parm1 + parm2; return val;}
2arg1
5arg2
7val
tmp
References• Returning a reference• never return a reference a local object
32
int arg1 = 2;int arg2 = 5;int sum = add(arg1, arg2);
int& add( int& parm1, int& parm2){ int val = parm1 + parm2; return val;}
2arg1
5arg2
7val
sum
Questions?
33
Pointers• Pointers are aliases that “point” to other variables• its just another name for an object
• Pointer is a compound type• type *variable;• e.g., int *foo;• should be read from right to left:
“foo is a pointer to an int”
34
Pointers• Alternate (dangerous) way to define pointers• type* variable;• e.g., int* foo;• dangerous: int* pval1, pval2;• pval1 is a pointer to an int• pval2 is an int• properly: int *pval1, *pval2;
35
Pointers• Pointers store the address of the object they alias• this gives us lots of power• more power than references• also more rope
• We need to be able to get the address of objects• use the address-of operator &• e.g., the integer pointer pval is assigned the address of valint val = 7;int *pval = &val;
• can use & on any value that can be on the left-side of an assignment• called lvalues• e.g., variables but not literals 36
Pointers• Valid pointers can have 3 possible values• address of a specific object• one address past the end of a specific object• 0 (or NULL)
• Initializing pointers• pointers do not need to be bound to an object immediately• not valid until initialized to 1 of 3 values above
• Legal assignments to (initialization of) pointers1. constant expression with a value of 02. address of an object with the correct type3. one address past the end of an object4. another valid pointer of the same type 37
Pointers
38
int aval = 21;int *pval1 = &aval;
21aval
pval1
Pointers
39
int aval = 21;int *pval1 = &aval;
21aval
pval1
Pointers
40
int aval = 21;int *pval1 = &aval;
int bval = 5;int *pval2 = &bval;
21aval
pval1
5bval
pval2
Pointers
41
int aval = 21;int *pval1 = &aval;
int bval = 5;int *pval2 = &bval;
pval1 = pval2;
21aval
pval1
5bval
pval2
Pointers• Uninitialized pointers• have some address made up from garbage• whatever was in that memory before• using them is dangerous, may overwrite other objects memory• like a wild card pointer• DO NOT LEAVE POINTERS LAYING AROUND UNINITIALIZED
42
Pointers• Getting access to the object• not automatic like references• need to use the * operator• e.g.,int val = 8;int *pval = &val;cout << *pval << endl;
• Dereferencing a pointer returns the object (an lval)• can assign new data to object• or modify object
43
Pointers
44
int aval = 21;int *pval1 = &aval;
21aval
pval1
Pointers
45
int aval = 21;int *pval1 = &aval;
*pval1 = 5;
21 5aval
pval1
Pointers
46
int aval = 21;int *pval1 = &aval;
*pval1 = 5;
(*pval1)++;
5 6aval
pval1
Pointers• We can also have pointers to pointers• a pointer stores an address of an object• a pointer is an object and also has an address
(different from the one it stores)• just add another * in the initialization to make a pointer to
a pointer• dereferencing a pointer to a pointer, yields the pointer• must dereference twice (**) to get to the object
47
Pointers
48
int aval = 21;int *pval1 = &aval;int **ppval = &pval1;
int bval = 5;int *pval2 = &bval;
21aval
pval1
5bval
pval2
ppval
Pointers
49
int aval = 21;int *pval1 = &aval;int **ppval = &pval1;
int bval = 5;int *pval2 = &bval;
ppval = &pval2;
21aval
pval1
5bval
pval2
ppval
Pointers
50
int aval = 21;int *pval1 = &aval;int **ppval = &pval1;
int bval = 5;int *pval2 = &bval;
ppval = &pval2;**ppval = 8;
21aval
pval1
5 8bval
pval2
ppval
Pointers and Functions
51
int arg1 = 7;int arg2 = 15;swap(&arg1, &arg2);
void swap(int *parm1, int *parm2){ int tmp = *parm1; *parm1 = *parm2; *parm2 = tmp;}
7arg1
15arg2
Pointers and Functions
52
int arg1 = 7;int arg2 = 15;swap(&arg1, &arg2);
void swap(int *parm1, int *parm2){ int tmp = *parm1; *parm1 = *parm2; *parm2 = tmp;}
7arg1
15arg2
parm2
parm1
Pointers and Functions
53
int arg1 = 7;int arg2 = 15;swap(&arg1, &arg2);
void swap(int *parm1, int *parm2){ int tmp = *parm1; *parm1 = *parm2; *parm2 = tmp;}
7 15
15 7
parm1
arg1
arg2
parm2
Pointers and Functions
54
int a = 7;int b = 15int *arg1 = &a;int *arg2 = &b;swap_ptr(arg1, arg2);
void swap_ptr( int *parm1, int *parm2){ int* tmp = parm1; parm1 = parm2; parm2 = tmp;}
7
15
arg1
arg2
Pointers and Functions
55
int a = 7;int b = 15int *arg1 = &a;int *arg2 = &b;swap_ptr(arg1, arg2);
void swap_ptr( int *parm1, int *parm2){ int* tmp = parm1; parm1 = parm2; parm2 = tmp;}
7
15
parm1
arg1
arg2
parm2
Pointers and Functions
56
int a = 7;int b = 15int *arg1 = &a;int *arg2 = &b;swap_ptr(arg1, arg2);
void swap_ptr( int *parm1, int *parm2){ int* tmp = parm1; parm1 = parm2; parm2 = tmp;}
7
15
parm2
arg1
arg2
parm1
Pointers and Functions
57
int a = 7;int b = 15int *arg1 = &a;int *arg2 = &b;swap_ptr(arg1, arg2);
void swap_ptr( int *&parm1, int *&parm2){ int* tmp = parm1; parm1 = parm2; parm2 = tmp;}
7
15
parm2
arg1
arg2
parm1
Pointers and Functions• Never return a pointer to a local object• for the same reasons it is a problem with references
58
Pointers and const• We can have pointers to constant objects• const type *name;• read: name may point to a type that is constant• e.g., const double dbl = 3.7;const double dbl2 = 4.5;const double *pdbl = &dbl;
• it is illegal to try to modify a constant object, even with a pointer• e.g., *pdbl = 2.4; // ERROR
• it is not illegal to assign the pointer to a different object• e.g.,pdbl = &dbl2; 59
Pointers and const• We can have pointers to constant objects• can also point to non-constant objects• e.g., double dbl = 3.7;const double *pdbl = &dbl;
• cannot modify non-constant objects using a pointer to a constant object
• e.g.,*pdbl = 7.1;
• even though the data can be modified by other aliases• e.g.,dbl = 7.1;
60
Pointers and const• We can have also have constant pointers to
non-constant objects• type *const name = …;• means we cannot reassign (rebind) the pointer to another object• must initialize when we create it• e.g.,int val = 7;int val2 = 10;int *const cpval = &val;*cpval = 15; // OKcpval = &val2; // COMPILE ERROR
61
Pointers and const• We can have also have constant pointers to
constant objects• const type *const name = …;• means we cannot reassign (rebind) the pointer to another object• must initialize when we create it• and we cannot modify the object• e.g.,const int val = 7;const int *const cpval = &val;*cpval = 15; // COMPILE ERRORcpval = &val2; // COMPILE ERROR
62
Pointers and Arrays• An array variable is really (sort of) a pointer to the first item in
the array• We can get pointers to elements in the array also• using address-of operator (&)
63
13579
oddsint odds[] = {1,3,5,7,9};int* podds = odds; //OKint* podds = &odds; //ERROR
int* p3rd = &odds[2];podds
p3rd
Pointers and Arrays• Pointer arithmetic• adding/subtracting an integer to a pointer yields a pointer• use to move around an array• e.g., jump 2 aheadint odds[4] = {1,3,5,7};int* podds = odds;podds = podds + 2; // points to 5
• e.g., pointer to one past the end of the arraypodds = podds + 4;
• Dangerous to dereference pointer one past the end of an array• OK to use to compare to other pointer
• Legal but very dangerous to increment pointer more than 1 past the end (or before the beginning) 64
Pointers and Arrays• Pointer arithmetic• can dereference result of pointer arithmetic• e.g.,int odds[4] = {1,3,5,7};int last_odd = *(odds + 3);
• Parenthesis are crucial here
65
Pointers and Arrays• Subscripts• subscript (e.g., a[4]) is just short hand for: “add 4 to the pointer a
and dereference the result”• can use subscript with any pointer• e.g.,int odds[4] = {1,3,5,7};int* p_end = &odds[4];int last = p_end[-1]; // last item (7)
66
Questions?
67