Vous êtes sur la page 1sur 31

CS142- Programming

Fall 2016

Lecture 4: C++ Primer Part 4

Malek Smaoui

Outline
Learn about pointers and dynamic memory
allocation
Chapter 2 from textbook
Chapter 6 www.learncpp.com

Learn about linked lists

Malek Smaoui

Pointers
C/C++ allows the programmer to have access to
memory addresses through pointers: one of the most
powerful and confusing aspects of the C language.
A pointer is a variable that stores the address of
another variable.
Pointer declaration: type * pointer_name;
The type corresponds to the data item being pointed to
by that pointer
exp:
int *pnPtr; // a pointer to an integer value
double *pdPtr; // a pointer to a double value

Malek Smaoui

Assigning addresses to pointer


Since addresses of memory used by a program
change at each execution, pointers can not be
assigned literal values.
Pointers can be assigned addresses of other
variables via the address-of operator &
(ampersand)
exp:
int nValue = 5;
int *pnPtr = &nValue;
// assign address of nValue to pnPtr

The types of the variable and the pointer have to


match
Malek Smaoui

Pointers: simple example


A pointer itself is stored in memory and has an
address
int nValue = 5;
int *pnPtr = &nValue; // assign address of nValue to pnPtr
cout << &nValue << endl; // print the address of variable
// nValue
cout << pnPtr << endl;
cout << &pnPtr << endl;

An execution of this code snippet could give


0x28ff44
0x28ff44
0x28ff40

Interpreted as

0x28ff40

0x28ff44

pnPtr
0x28ff44

nValue
5

Malek Smaoui

Dereferencing pointers
Pointers can be used to read and write to the variable or
memory location they point to via the dereference
operator *
A dereferenced pointer evaluates to the contents of the
address it is pointing to.
int nValue = 5;
cout << &nValue; // prints address of nValue
cout << nValue; // prints contents of nValue
int *pnPtr = &nValue; // pnPtr points to nValue
cout << pnPtr; // prints address held in pnPtr,
// which is &nValue
cout << *pnPtr; // prints contents pointed to
//by pnPtr, which is contents
//of nValue
Malek Smaoui

Another example
int x, y;
int *p1, *p2;

x = 42;
y = 163

p1 = &y;
p2 = &x;

alternatively

Malek Smaoui

Another example
p1 = p2;

*p1 = 17;

alternatively

Malek Smaoui

*p1 = *p2;

The null pointer


Its a pointer that points to nothing (the 0
value for pointers)
int *pnPtr;
pnPtr = 0;
// also equivalent to
int *pnPtr = 0;
//also equivalent to
int *pnPtr = NULL;
cout << pnPtr; // prints 0
cout << *pnPtr; // program crash
Malek Smaoui

The size of pointers


A pointer stores an address:
on 32-bit machines, addresses are 4 bytes so the size of a
pointer is 4 bytes
on 64-bit machines, addresses are 8 bytes so the size of a
pointer is 8 bytes

The size of pointer does not depend on its type


char *pchValue; // chars are 1 byte
int *pnValue; // ints are usually 4 bytes
struct Something
{
int nX, nY, nZ;
};
Something *psValue; // Something is probably 12 bytes
cout << sizeof(pchValue) << endl; // prints 4 (or 8)
cout << sizeof(pnValue) << endl; // prints 4 (or 8)
cout << sizeof(psValue) << endl; // prints 4 (or 8)

Pointer to struct
Pointers can point to any custom data type
Selecting a struct field from a dereferenced pointer to
the struct uses different operators:
(->) instead of the (*) and the (.)
exp:
struct Something
{
int nX, nY, nZ;
};
Something sValue;
Something *psValue = &sValue;
psValue->nX = 3;
psValue->nY = psValue->nX+1;

Malek Smaoui

Passing arguments by address


Passing the address
of the argument
variable instead of
the variable itself.
The function can
change the value of
the variable being
pointed to by
dereferencing the
pointer that is
passed as parameter.

void foo(int *pValue)


{
*pValue = 6;
}
int main()
{
int nValue = 5;
cout << "nValue = ;
cout << nValue << endl;
foo(&nValue);
cout << "nValue = ;
cout << nValue << endl;
return 0;
}

Pointers and Arrays


(The name of) An array is a pointer that points to
the first element of the array:
possibility of assigning an array to a pointer (of the
same type)
pointer and array names used interchangeably
possibility of dereferencing an array to access content
of first element
possibility of using a pointer with subscript operator
passing an array to a function is equivalent to passing
a pointer of the same array type instead
Malek Smaoui

Simple example
int values[20];
int *pValues;
pValues = values;
pValues[10] = 201;
//same as values[10]= 201;
*values = 20;
// same as *pValues = 20
// also same as values[0]=20;

Malek Smaoui

Pointer arithmetic
C allows integer addition or subtraction operations on
pointers. But, no pointer addition or subtraction.
Pointer arithmetic is not address arithmetic: adding 1
to a pointer is equivalent to adding
sizeof(pointer_type) to the address stored in the
pointer i.e. pointing to the next element of the pointer
type
If the pointer points to an array, pointer arithmetic
allow pointing to different elements if the array
commonly used case of pointer arithmetic
most common use is in loops, although indices are
preferred
Malek Smaoui

Example
int nValue = 7;
int *pnPtr = &nValue;

cout << pnPtr << endl;


// if this prints 0012FF7C
cout << ++pnPtr << endl;
// this will print 0012FF80 = 0012FF7C + 4
cout << pnPtr+2 << endl;
// this will print 0012FF88 = 0012FF80 + 2*4
int anArray[5] = { 9, 7, 5, 3, 1 };
cout << *(anArray+1) << endl; // prints 7

Malek Smaoui

Dynamic memory allocation


Main advantage from using pointers
Allows allocating memory which amount is
not known at compile time
Overcomes static variable and array
declaration:
memory waste
artificial limitations or buffer overflow

Malek Smaoui

new and delete operators


Allocate memory as needed using the new
operator and pointers:
type *pointer_name;
pointer_name = new type; // single variable
pointer_name = new type[nbr_elmnt]; // array

Free (deallocate) memory previously allocated


with new using the delete operator
delete pointer_name;
delete[] pointer_name;
Malek Smaoui

Example
int *pnValue = new int; // dynamically
// allocate an integer
*pnValue = 7; // assign 7 to this integer
delete pnValue; // free that integer

int nSize = 12;


int *pnArray = new int[nSize];
// note: nSize does not need to be constant!
pnArray[4] = 7;
delete[] pnArray;
Malek Smaoui

Another example
Dynamically allocated memory has no variable
name, only accessible through the pointer
name
char * ptr;

0x12FF80
ptr
???

ptr = new char;

*ptr = B;

0x12FF80

0x12FF80

ptr
0x28ff40

ptr
0x28ff40

0x28ff40

0x28ff40
66 (B)

Another example
cout << *ptr;
// prints B

delete ptr;

0x12FF80
ptr
???

Malek Smaoui

Good practices:
- Initialize pointers to 0 or
NULL if not allocated at
declaration.
- Deallocated pointers are
not set to 0 automatically.
Setting to 0 freed pointers
reduces sources of
pointer misuse

The stack and the heap


A programs memory is divided into:
code area: compiled program (executable)
globals area: global variables
heap: dynamically allocated variables
stack: parameters and local variables

Memory allocated through local scope pointer


that is not freed while pointer is active is
never freed until program exists: memory leak
Malek Smaoui

Program memory
int global = 0;
int main (int arg)
{
float local;
char *ptr;
ptr = new char[100];
local = 0;
local += 10*5;
..
.
foo();
. /* return addr */
.
return 0;

Local variables
Return address

Dynamically
allocated
Global variables
Program code

}
Malek Smaoui

Memory reallocation
Memory allocated with new can NOT be extended or
reduced on demand
unless programmer implements the necessary mechanism

C-style allocation with malloc() allows extension


of arrays through reallocation with realloc()
Reallocation sometimes expensive: would necessitate
(transparently) moving data around in the heap
http://www.cplusplus.com/reference/cstdlib/malloc/
http://www.cplusplus.com/reference/cstdlib/realloc/
Malek Smaoui

Linked lists
A data structure to store aggregate data
allocating memory on demand for each new
element
Storage is not necessarily contiguous in
memory: linked lists are not indexable
Each element has two components:
actual data (int, float, char, struct, enum, .)
pointer to next element
Malek Smaoui

Linked lists

Malek Smaoui

Doubly linked list

Malek Smaoui

Linked lists
Advantage of linked lists over arrays:
No needed previous knowledge of number of
elements: memory allocated on demand
insertion and deletion of element is trivial, does
not need to move data around

Advantage of arrays over linked lists:


less memory usage
less implementation effort
Malek Smaoui

Example of use
struct node {
int x;
node *next;
};
int main()
{
node *root = 0; // This will be the unchanging first
root = new node; // Now root points to a node struct
root->next = 0; // The node root points to has its
// next pointer set equal to a null pointer
root->x = 5; // By using the -> operator, you can modify the
// node a pointer (root in this case) points to.
node *newNode = new node; // adding a new element
root->next = newNode;
newNode->x = 6;
newNode->next = 0;
}

Implementation
Effective use of a linked list requires the
implementation of few routines according to
the users needs:
add an element at the end
find element (eventually return position)
insert element at position
delete element
print elements

Malek Smaoui

Exercise
Using the linked list definition in the example,
write the following functions:
void addNode(node *root, int x);
int findNode(node *root, int y, node *found);
void printList(node *root);
void insertNode(node *root, int x, int pos);
void deleteNode(node *root, int y);

Malek Smaoui

Vous aimerez peut-être aussi