advanced operating systems moving to c++ 2015-10-28 · giuseppe massari advanced operating systems...
TRANSCRIPT
Advanced Operating SystemsMoving to C++
Giuseppe Massarigiuseppemassaripolimiit
Advanced Operating SystemsGiuseppe Massari
442Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
443Program memory
Memory layout Once loaded in the main memory a program is typicallydivided into segments
TEXT Program instructions
DATA Initialized variables
BSS Uninitialized or zeroed variables
STACK Local variables and return address of functions
HEAP Dynamically allocated data ie allocateddeshyallocated at runshytime
Advanced Operating SystemsGiuseppe Massari
444Program memory
Memory allocation In C programs dynamic memory allocation and deshyallocation is performed through malloc() and free() functions
In C++ programs operators new and delete are usedFor dynamic array allocation new hellip[] delete[]
newdelete call class constructor and destructor respectivelyDo not mix mallocfree with newdelete usage
Do not use mallocfree with C++ objects since they do not call the class constructordestructor
char buff = malloc(buff_size)char buff = malloc(buff_size) free(buff)free(buff)
char buff = new char[5]
Object obj = new Object()
char buff = new char[5]
Object obj = new Object()
delete[] buff
delete obj
delete[] buff
delete obj
Advanced Operating SystemsGiuseppe Massari
445Program memory
Memory allocation Example
static resultunsigned int count = 20
int main()
int numchar buff = new char[4]
hellipdelete[] valuereturn 0
static resultunsigned int count = 20
int main()
int numchar buff = new char[4]
hellipdelete[] valuereturn 0
result
count
main numbuff
ldquordquo
Advanced Operating SystemsGiuseppe Massari
446Memory allocation common errors
Memory leak Memory allocated but NOT released Application continuously increase memory consumption
Reducing the availability for other applications Performance slow down
Operating system may reshymap the virtual memory page to the hard drive Application or even the system may stop working
Unpredictable behaviour when system memory resource limits are reached
Sources We forgotten the related delete call for some new We changed the value of a pointer variable
No other variables point to the previously dynamically allocated data
Such data becomes unreachable
Advanced Operating SystemsGiuseppe Massari
447Memory allocation common errors
Memory corruption Memory location alteration without an explicit assignment
Attempt of freeing an already freed memory location (dangling pointer)
Attempt of accessing a freed (or not allocated yet) memory location
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
int main() char buffcout ltlt buff ltlt endl
int main() char buffcout ltlt buff ltlt endl
$ programSegmentation fault(core dumped)
$ programSegmentation fault(core dumped)
Advanced Operating SystemsGiuseppe Massari
448Functions
Passing parameters By value
Passed variablesobjects are COPIED into the called function stack
By address (C approach)Caller passes the address of the objectvariable to the callee (NO COPY)
Callee can modify the content of the variableobject
By reference (C++ approach)Same effect of passing by address (NO COPY)
Callee can modify the content of the variableobject
void func(Object var)void func(Object var) func(var) callfunc(var) call
void func(Object var)void func(Object var) func(ampvar) callfunc(ampvar) call
void func(Object amp var)void func(Object amp var) func(var) callfunc(var) call
Advanced Operating SystemsGiuseppe Massari
449Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4410Classes
Syntax A C++ class can include a public and private sections (keywords public and private) to set the visibility level of member data (attributes) and member functions (methods)
Good practice member definition and member implementation placed into separated files
Definition header file (rarr h hh) Implementation rarr cpp cc Member function implementation syntaxltfunction typegt ClassNameFunctionName()
Accessor methods (Get()) are tagged with the keyword const
The class definition is closed by a semicolon ()
Advanced Operating SystemsGiuseppe Massari
4411Classes
Syntax
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4412Classes
Constructors A function having the same class name but not returning any type Called every time an instance of a class is created If not provided the compiler will generate the code for one A class can have multiple constructors with different argument lists
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
442Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
443Program memory
Memory layout Once loaded in the main memory a program is typicallydivided into segments
TEXT Program instructions
DATA Initialized variables
BSS Uninitialized or zeroed variables
STACK Local variables and return address of functions
HEAP Dynamically allocated data ie allocateddeshyallocated at runshytime
Advanced Operating SystemsGiuseppe Massari
444Program memory
Memory allocation In C programs dynamic memory allocation and deshyallocation is performed through malloc() and free() functions
In C++ programs operators new and delete are usedFor dynamic array allocation new hellip[] delete[]
newdelete call class constructor and destructor respectivelyDo not mix mallocfree with newdelete usage
Do not use mallocfree with C++ objects since they do not call the class constructordestructor
char buff = malloc(buff_size)char buff = malloc(buff_size) free(buff)free(buff)
char buff = new char[5]
Object obj = new Object()
char buff = new char[5]
Object obj = new Object()
delete[] buff
delete obj
delete[] buff
delete obj
Advanced Operating SystemsGiuseppe Massari
445Program memory
Memory allocation Example
static resultunsigned int count = 20
int main()
int numchar buff = new char[4]
hellipdelete[] valuereturn 0
static resultunsigned int count = 20
int main()
int numchar buff = new char[4]
hellipdelete[] valuereturn 0
result
count
main numbuff
ldquordquo
Advanced Operating SystemsGiuseppe Massari
446Memory allocation common errors
Memory leak Memory allocated but NOT released Application continuously increase memory consumption
Reducing the availability for other applications Performance slow down
Operating system may reshymap the virtual memory page to the hard drive Application or even the system may stop working
Unpredictable behaviour when system memory resource limits are reached
Sources We forgotten the related delete call for some new We changed the value of a pointer variable
No other variables point to the previously dynamically allocated data
Such data becomes unreachable
Advanced Operating SystemsGiuseppe Massari
447Memory allocation common errors
Memory corruption Memory location alteration without an explicit assignment
Attempt of freeing an already freed memory location (dangling pointer)
Attempt of accessing a freed (or not allocated yet) memory location
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
int main() char buffcout ltlt buff ltlt endl
int main() char buffcout ltlt buff ltlt endl
$ programSegmentation fault(core dumped)
$ programSegmentation fault(core dumped)
Advanced Operating SystemsGiuseppe Massari
448Functions
Passing parameters By value
Passed variablesobjects are COPIED into the called function stack
By address (C approach)Caller passes the address of the objectvariable to the callee (NO COPY)
Callee can modify the content of the variableobject
By reference (C++ approach)Same effect of passing by address (NO COPY)
Callee can modify the content of the variableobject
void func(Object var)void func(Object var) func(var) callfunc(var) call
void func(Object var)void func(Object var) func(ampvar) callfunc(ampvar) call
void func(Object amp var)void func(Object amp var) func(var) callfunc(var) call
Advanced Operating SystemsGiuseppe Massari
449Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4410Classes
Syntax A C++ class can include a public and private sections (keywords public and private) to set the visibility level of member data (attributes) and member functions (methods)
Good practice member definition and member implementation placed into separated files
Definition header file (rarr h hh) Implementation rarr cpp cc Member function implementation syntaxltfunction typegt ClassNameFunctionName()
Accessor methods (Get()) are tagged with the keyword const
The class definition is closed by a semicolon ()
Advanced Operating SystemsGiuseppe Massari
4411Classes
Syntax
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4412Classes
Constructors A function having the same class name but not returning any type Called every time an instance of a class is created If not provided the compiler will generate the code for one A class can have multiple constructors with different argument lists
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
443Program memory
Memory layout Once loaded in the main memory a program is typicallydivided into segments
TEXT Program instructions
DATA Initialized variables
BSS Uninitialized or zeroed variables
STACK Local variables and return address of functions
HEAP Dynamically allocated data ie allocateddeshyallocated at runshytime
Advanced Operating SystemsGiuseppe Massari
444Program memory
Memory allocation In C programs dynamic memory allocation and deshyallocation is performed through malloc() and free() functions
In C++ programs operators new and delete are usedFor dynamic array allocation new hellip[] delete[]
newdelete call class constructor and destructor respectivelyDo not mix mallocfree with newdelete usage
Do not use mallocfree with C++ objects since they do not call the class constructordestructor
char buff = malloc(buff_size)char buff = malloc(buff_size) free(buff)free(buff)
char buff = new char[5]
Object obj = new Object()
char buff = new char[5]
Object obj = new Object()
delete[] buff
delete obj
delete[] buff
delete obj
Advanced Operating SystemsGiuseppe Massari
445Program memory
Memory allocation Example
static resultunsigned int count = 20
int main()
int numchar buff = new char[4]
hellipdelete[] valuereturn 0
static resultunsigned int count = 20
int main()
int numchar buff = new char[4]
hellipdelete[] valuereturn 0
result
count
main numbuff
ldquordquo
Advanced Operating SystemsGiuseppe Massari
446Memory allocation common errors
Memory leak Memory allocated but NOT released Application continuously increase memory consumption
Reducing the availability for other applications Performance slow down
Operating system may reshymap the virtual memory page to the hard drive Application or even the system may stop working
Unpredictable behaviour when system memory resource limits are reached
Sources We forgotten the related delete call for some new We changed the value of a pointer variable
No other variables point to the previously dynamically allocated data
Such data becomes unreachable
Advanced Operating SystemsGiuseppe Massari
447Memory allocation common errors
Memory corruption Memory location alteration without an explicit assignment
Attempt of freeing an already freed memory location (dangling pointer)
Attempt of accessing a freed (or not allocated yet) memory location
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
int main() char buffcout ltlt buff ltlt endl
int main() char buffcout ltlt buff ltlt endl
$ programSegmentation fault(core dumped)
$ programSegmentation fault(core dumped)
Advanced Operating SystemsGiuseppe Massari
448Functions
Passing parameters By value
Passed variablesobjects are COPIED into the called function stack
By address (C approach)Caller passes the address of the objectvariable to the callee (NO COPY)
Callee can modify the content of the variableobject
By reference (C++ approach)Same effect of passing by address (NO COPY)
Callee can modify the content of the variableobject
void func(Object var)void func(Object var) func(var) callfunc(var) call
void func(Object var)void func(Object var) func(ampvar) callfunc(ampvar) call
void func(Object amp var)void func(Object amp var) func(var) callfunc(var) call
Advanced Operating SystemsGiuseppe Massari
449Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4410Classes
Syntax A C++ class can include a public and private sections (keywords public and private) to set the visibility level of member data (attributes) and member functions (methods)
Good practice member definition and member implementation placed into separated files
Definition header file (rarr h hh) Implementation rarr cpp cc Member function implementation syntaxltfunction typegt ClassNameFunctionName()
Accessor methods (Get()) are tagged with the keyword const
The class definition is closed by a semicolon ()
Advanced Operating SystemsGiuseppe Massari
4411Classes
Syntax
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4412Classes
Constructors A function having the same class name but not returning any type Called every time an instance of a class is created If not provided the compiler will generate the code for one A class can have multiple constructors with different argument lists
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
444Program memory
Memory allocation In C programs dynamic memory allocation and deshyallocation is performed through malloc() and free() functions
In C++ programs operators new and delete are usedFor dynamic array allocation new hellip[] delete[]
newdelete call class constructor and destructor respectivelyDo not mix mallocfree with newdelete usage
Do not use mallocfree with C++ objects since they do not call the class constructordestructor
char buff = malloc(buff_size)char buff = malloc(buff_size) free(buff)free(buff)
char buff = new char[5]
Object obj = new Object()
char buff = new char[5]
Object obj = new Object()
delete[] buff
delete obj
delete[] buff
delete obj
Advanced Operating SystemsGiuseppe Massari
445Program memory
Memory allocation Example
static resultunsigned int count = 20
int main()
int numchar buff = new char[4]
hellipdelete[] valuereturn 0
static resultunsigned int count = 20
int main()
int numchar buff = new char[4]
hellipdelete[] valuereturn 0
result
count
main numbuff
ldquordquo
Advanced Operating SystemsGiuseppe Massari
446Memory allocation common errors
Memory leak Memory allocated but NOT released Application continuously increase memory consumption
Reducing the availability for other applications Performance slow down
Operating system may reshymap the virtual memory page to the hard drive Application or even the system may stop working
Unpredictable behaviour when system memory resource limits are reached
Sources We forgotten the related delete call for some new We changed the value of a pointer variable
No other variables point to the previously dynamically allocated data
Such data becomes unreachable
Advanced Operating SystemsGiuseppe Massari
447Memory allocation common errors
Memory corruption Memory location alteration without an explicit assignment
Attempt of freeing an already freed memory location (dangling pointer)
Attempt of accessing a freed (or not allocated yet) memory location
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
int main() char buffcout ltlt buff ltlt endl
int main() char buffcout ltlt buff ltlt endl
$ programSegmentation fault(core dumped)
$ programSegmentation fault(core dumped)
Advanced Operating SystemsGiuseppe Massari
448Functions
Passing parameters By value
Passed variablesobjects are COPIED into the called function stack
By address (C approach)Caller passes the address of the objectvariable to the callee (NO COPY)
Callee can modify the content of the variableobject
By reference (C++ approach)Same effect of passing by address (NO COPY)
Callee can modify the content of the variableobject
void func(Object var)void func(Object var) func(var) callfunc(var) call
void func(Object var)void func(Object var) func(ampvar) callfunc(ampvar) call
void func(Object amp var)void func(Object amp var) func(var) callfunc(var) call
Advanced Operating SystemsGiuseppe Massari
449Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4410Classes
Syntax A C++ class can include a public and private sections (keywords public and private) to set the visibility level of member data (attributes) and member functions (methods)
Good practice member definition and member implementation placed into separated files
Definition header file (rarr h hh) Implementation rarr cpp cc Member function implementation syntaxltfunction typegt ClassNameFunctionName()
Accessor methods (Get()) are tagged with the keyword const
The class definition is closed by a semicolon ()
Advanced Operating SystemsGiuseppe Massari
4411Classes
Syntax
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4412Classes
Constructors A function having the same class name but not returning any type Called every time an instance of a class is created If not provided the compiler will generate the code for one A class can have multiple constructors with different argument lists
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
445Program memory
Memory allocation Example
static resultunsigned int count = 20
int main()
int numchar buff = new char[4]
hellipdelete[] valuereturn 0
static resultunsigned int count = 20
int main()
int numchar buff = new char[4]
hellipdelete[] valuereturn 0
result
count
main numbuff
ldquordquo
Advanced Operating SystemsGiuseppe Massari
446Memory allocation common errors
Memory leak Memory allocated but NOT released Application continuously increase memory consumption
Reducing the availability for other applications Performance slow down
Operating system may reshymap the virtual memory page to the hard drive Application or even the system may stop working
Unpredictable behaviour when system memory resource limits are reached
Sources We forgotten the related delete call for some new We changed the value of a pointer variable
No other variables point to the previously dynamically allocated data
Such data becomes unreachable
Advanced Operating SystemsGiuseppe Massari
447Memory allocation common errors
Memory corruption Memory location alteration without an explicit assignment
Attempt of freeing an already freed memory location (dangling pointer)
Attempt of accessing a freed (or not allocated yet) memory location
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
int main() char buffcout ltlt buff ltlt endl
int main() char buffcout ltlt buff ltlt endl
$ programSegmentation fault(core dumped)
$ programSegmentation fault(core dumped)
Advanced Operating SystemsGiuseppe Massari
448Functions
Passing parameters By value
Passed variablesobjects are COPIED into the called function stack
By address (C approach)Caller passes the address of the objectvariable to the callee (NO COPY)
Callee can modify the content of the variableobject
By reference (C++ approach)Same effect of passing by address (NO COPY)
Callee can modify the content of the variableobject
void func(Object var)void func(Object var) func(var) callfunc(var) call
void func(Object var)void func(Object var) func(ampvar) callfunc(ampvar) call
void func(Object amp var)void func(Object amp var) func(var) callfunc(var) call
Advanced Operating SystemsGiuseppe Massari
449Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4410Classes
Syntax A C++ class can include a public and private sections (keywords public and private) to set the visibility level of member data (attributes) and member functions (methods)
Good practice member definition and member implementation placed into separated files
Definition header file (rarr h hh) Implementation rarr cpp cc Member function implementation syntaxltfunction typegt ClassNameFunctionName()
Accessor methods (Get()) are tagged with the keyword const
The class definition is closed by a semicolon ()
Advanced Operating SystemsGiuseppe Massari
4411Classes
Syntax
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4412Classes
Constructors A function having the same class name but not returning any type Called every time an instance of a class is created If not provided the compiler will generate the code for one A class can have multiple constructors with different argument lists
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
446Memory allocation common errors
Memory leak Memory allocated but NOT released Application continuously increase memory consumption
Reducing the availability for other applications Performance slow down
Operating system may reshymap the virtual memory page to the hard drive Application or even the system may stop working
Unpredictable behaviour when system memory resource limits are reached
Sources We forgotten the related delete call for some new We changed the value of a pointer variable
No other variables point to the previously dynamically allocated data
Such data becomes unreachable
Advanced Operating SystemsGiuseppe Massari
447Memory allocation common errors
Memory corruption Memory location alteration without an explicit assignment
Attempt of freeing an already freed memory location (dangling pointer)
Attempt of accessing a freed (or not allocated yet) memory location
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
int main() char buffcout ltlt buff ltlt endl
int main() char buffcout ltlt buff ltlt endl
$ programSegmentation fault(core dumped)
$ programSegmentation fault(core dumped)
Advanced Operating SystemsGiuseppe Massari
448Functions
Passing parameters By value
Passed variablesobjects are COPIED into the called function stack
By address (C approach)Caller passes the address of the objectvariable to the callee (NO COPY)
Callee can modify the content of the variableobject
By reference (C++ approach)Same effect of passing by address (NO COPY)
Callee can modify the content of the variableobject
void func(Object var)void func(Object var) func(var) callfunc(var) call
void func(Object var)void func(Object var) func(ampvar) callfunc(ampvar) call
void func(Object amp var)void func(Object amp var) func(var) callfunc(var) call
Advanced Operating SystemsGiuseppe Massari
449Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4410Classes
Syntax A C++ class can include a public and private sections (keywords public and private) to set the visibility level of member data (attributes) and member functions (methods)
Good practice member definition and member implementation placed into separated files
Definition header file (rarr h hh) Implementation rarr cpp cc Member function implementation syntaxltfunction typegt ClassNameFunctionName()
Accessor methods (Get()) are tagged with the keyword const
The class definition is closed by a semicolon ()
Advanced Operating SystemsGiuseppe Massari
4411Classes
Syntax
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4412Classes
Constructors A function having the same class name but not returning any type Called every time an instance of a class is created If not provided the compiler will generate the code for one A class can have multiple constructors with different argument lists
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
447Memory allocation common errors
Memory corruption Memory location alteration without an explicit assignment
Attempt of freeing an already freed memory location (dangling pointer)
Attempt of accessing a freed (or not allocated yet) memory location
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
int main() char buff = new char[4]delete[] buffhellipdelete[] buff
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
$ program Error in `program double free or corruption 0x00000000011a5040
Aborted (core dumped)
int main() char buffcout ltlt buff ltlt endl
int main() char buffcout ltlt buff ltlt endl
$ programSegmentation fault(core dumped)
$ programSegmentation fault(core dumped)
Advanced Operating SystemsGiuseppe Massari
448Functions
Passing parameters By value
Passed variablesobjects are COPIED into the called function stack
By address (C approach)Caller passes the address of the objectvariable to the callee (NO COPY)
Callee can modify the content of the variableobject
By reference (C++ approach)Same effect of passing by address (NO COPY)
Callee can modify the content of the variableobject
void func(Object var)void func(Object var) func(var) callfunc(var) call
void func(Object var)void func(Object var) func(ampvar) callfunc(ampvar) call
void func(Object amp var)void func(Object amp var) func(var) callfunc(var) call
Advanced Operating SystemsGiuseppe Massari
449Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4410Classes
Syntax A C++ class can include a public and private sections (keywords public and private) to set the visibility level of member data (attributes) and member functions (methods)
Good practice member definition and member implementation placed into separated files
Definition header file (rarr h hh) Implementation rarr cpp cc Member function implementation syntaxltfunction typegt ClassNameFunctionName()
Accessor methods (Get()) are tagged with the keyword const
The class definition is closed by a semicolon ()
Advanced Operating SystemsGiuseppe Massari
4411Classes
Syntax
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4412Classes
Constructors A function having the same class name but not returning any type Called every time an instance of a class is created If not provided the compiler will generate the code for one A class can have multiple constructors with different argument lists
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
448Functions
Passing parameters By value
Passed variablesobjects are COPIED into the called function stack
By address (C approach)Caller passes the address of the objectvariable to the callee (NO COPY)
Callee can modify the content of the variableobject
By reference (C++ approach)Same effect of passing by address (NO COPY)
Callee can modify the content of the variableobject
void func(Object var)void func(Object var) func(var) callfunc(var) call
void func(Object var)void func(Object var) func(ampvar) callfunc(ampvar) call
void func(Object amp var)void func(Object amp var) func(var) callfunc(var) call
Advanced Operating SystemsGiuseppe Massari
449Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4410Classes
Syntax A C++ class can include a public and private sections (keywords public and private) to set the visibility level of member data (attributes) and member functions (methods)
Good practice member definition and member implementation placed into separated files
Definition header file (rarr h hh) Implementation rarr cpp cc Member function implementation syntaxltfunction typegt ClassNameFunctionName()
Accessor methods (Get()) are tagged with the keyword const
The class definition is closed by a semicolon ()
Advanced Operating SystemsGiuseppe Massari
4411Classes
Syntax
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4412Classes
Constructors A function having the same class name but not returning any type Called every time an instance of a class is created If not provided the compiler will generate the code for one A class can have multiple constructors with different argument lists
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
449Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4410Classes
Syntax A C++ class can include a public and private sections (keywords public and private) to set the visibility level of member data (attributes) and member functions (methods)
Good practice member definition and member implementation placed into separated files
Definition header file (rarr h hh) Implementation rarr cpp cc Member function implementation syntaxltfunction typegt ClassNameFunctionName()
Accessor methods (Get()) are tagged with the keyword const
The class definition is closed by a semicolon ()
Advanced Operating SystemsGiuseppe Massari
4411Classes
Syntax
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4412Classes
Constructors A function having the same class name but not returning any type Called every time an instance of a class is created If not provided the compiler will generate the code for one A class can have multiple constructors with different argument lists
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4410Classes
Syntax A C++ class can include a public and private sections (keywords public and private) to set the visibility level of member data (attributes) and member functions (methods)
Good practice member definition and member implementation placed into separated files
Definition header file (rarr h hh) Implementation rarr cpp cc Member function implementation syntaxltfunction typegt ClassNameFunctionName()
Accessor methods (Get()) are tagged with the keyword const
The class definition is closed by a semicolon ()
Advanced Operating SystemsGiuseppe Massari
4411Classes
Syntax
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4412Classes
Constructors A function having the same class name but not returning any type Called every time an instance of a class is created If not provided the compiler will generate the code for one A class can have multiple constructors with different argument lists
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4411Classes
Syntax
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
ifndef PEOPLE_H_define PEOPLE_H_
include ltstringgt
class People public
People()int Walk()void Talk() const
privatestdstring nameint step_count
endif PEOPLE_H_
peopleh
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
include ltiostreamgtinclude peopleh
PeoplePeople()name(ldquoguyrdquo)step_count(0)
int PeopleWalk() return ++step_count
void PeopleTalk() conststdcout ltlt name
ltlt ldquo made rdquo ltlt step_countltlt ldquo stepsrdquo ltlt stdendl
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4412Classes
Constructors A function having the same class name but not returning any type Called every time an instance of a class is created If not provided the compiler will generate the code for one A class can have multiple constructors with different argument lists
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4412Classes
Constructors A function having the same class name but not returning any type Called every time an instance of a class is created If not provided the compiler will generate the code for one A class can have multiple constructors with different argument lists
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
class People public
People()People(stdstring _name)hellip
privatestdstring nameint step_count
hellip
peopleh
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
PeoplePeople()name(ldquoGuyrdquo)step_count(0)
PeoplePeople(stdstring _name)name(_name)step_count(0)
peoplecpp
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4413Classes
Constructors Called when we instantiate an object by declaring a variable of the class type or we dynamically allocate an object of the class type(see later)
int main()
People who1People who2()People simon(ldquoSimonrdquo)
who1Talk()who2Talk()simonTalk()
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
Guy made 0 stepsGuy made 0 stepsSimon made 0 steps
People() version is called
People(stdstring) version is called
Output
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4414Classes
Destructors Called when the object is going out of scope or it is explicitly deleted
Syntax ~ClassName() (no arguments)Very often qualified as ldquovirtualrdquo to prevent derived class from invoking thebase class destructor
Commonly includes the implementation of end of life actions eg cleanshyup code memory deallocation
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
class People public
People()People(stdstring _name)virtual ~People()
hellip peopleh
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
hellip People~People()
stdcout ltlt nameltlt ldquo im dyingrdquoltlt stdendl
hellip peoplecpp
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4415Classes
Copy constructors Special constructors having an object of the same class as argument If not implemented the compiler will automatically generate one The default implementation is a membershywise copy of the object
Membershywise copy can be expensiveWhat if member data are further complex objects
Depending on the class definition it may also lead to undesired behaviours
What if member data are pointers Pointer object ldquocomplexrdquo class types
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
PeoplePeople( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4416Classes
Copy constructors Example
Fred is created starting from Simon(do we want Fred to have the same Simons information)
Default copy constructor is called (membershywise copy)
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
int main()
People simon(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People fred(simon)fredTalk()
Simon made 3 stepsSimon made 3 steps
Simon made 3 stepsSimon made 3 steps
freds member data have been initialized to the same value of object simon
Output
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4417Classes
Copy constructors Creating a ldquoPeoplerdquo object starting from another one
Do we want the ldquonew personrdquo Fred to start with the number of steps of the Simon
Overload of the copy constructor implementing our custom versionSet step_count to zero since we are constructing a new object that hasnever walked before
Desired behaviour Just copy the name of the other person
PeoplePeople( const People amp other )
name = othernamestep_count = 0
PeoplePeople( const People amp other )
name = othernamestep_count = 0
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4418Classes
Copy constructors Example
We create a second ldquoSimonrdquo object
Custom copy constructor initializes the object using the same of the first Simon
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
int main()
People simon1(ldquoSimonrdquo)
for(int i=0 ilt3 ++i)simonWalk()
simonTalk()
People simon2(simon1)simon2Talk()
Simon made 3 stepsSimon made 0 steps
Simon made 3 stepsSimon made 0 steps
simon2 has the same name of simon1 but since it has just born it has never walked before
Output
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4419Classes
Object assignment Assignment operation is provided by the compiler Also in this case the default implementation is the membershywise copy of the object
Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
We can overload the assignment operator (ldquo=rdquo) tooSyntax similar to member function implementation but replacing the function name with operatorltoperator_symbolgt
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
People amp Peopleoperator=( const People amp other )
name = othernamestep_count = otherstep_count
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4420Classes
Object assignment Conversely from other OO languages (eg Java) the object variables content is a value and not a reference
An assignment operation lead to a copy of the entire object
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
int main()
People simon(ldquoSimonrdquo)People fred
fred = simonsimonWalk()simonTalk()
fredTalk()
Simon made 1 stepsSimon made 0 steps
Simon made 1 stepsSimon made 0 steps
Member data name value hasbeen copied
Walk() has updated only simon status
Output
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4421Classes
Object pointers Pointers allows multiple variables to jointly access the same object
Assignment operation copies the pointervalue ie the memory address
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
int main() People joe1 =
new People(ldquoJoerdquo)People joe2
joe2 = joe1joe1-gtWalk()joe1-gtTalk()joe2-gtTalk()
delete joe2return 0
mainjoe2joe1
ldquordquo0x8ed040
Joe made 1 stepsJoe made 1 steps
Joe made 1 stepsJoe made 1 steps
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4422Classes
Constant members Data or function members qualified with const keyword Constshyqualified variable are used to store data that should not be altered
Qualifier const applies to whatever is on its immediate left If there is nothing there applies to whatever is its immediate right
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
k is a variable pointer to a constant integerconst int k alternative syntax which does the sameint const k k is constant pointer to an integer variableint const k k is a constant pointer to a constant integerint const const k
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4423Classes
Constant members The const keyword can be used also in functions To specify a ldquoreadshyonlyrdquo function ie that does not change the object status (member data values)
To pass (by reference) arguments (typically objects) that we donot want to be modified
Function TalkWith() cannot access not const member functions of other To prevent alteration of returned variable of pointer types
Alteration attempts are detected at compileshytime
void Talk() constvoid Talk() const
void TalkWith(const People amp other)void TalkWith(const People amp other)
const People GetParent() constconst People GetParent() const
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4424Classes
Static members The static keyword can be used in a class definition for different purposes depending on if it is applied to data or functions
Static member data are variables shared among all the instancesMember data initialization cannot be performed in the class
Static member functions do not require a class instanceFunctions though to be meaningful at classshylevel instead of instanceshylevel
They cannot access non static members since not ldquobelongingrdquo to any instance
stdcoutltlt MyClassGetCount()ltlt stdendl
stdcoutltlt MyClassGetCount()ltlt stdendl
class MyClass myclasshstatic int count
class MyClass myclasshstatic int count
myclasscpp Initializationint MyClasscount = 0
myclasscpp Initializationint MyClasscount = 0
class MyClass myclasshpublic
static int GetCount()
class MyClass myclasshpublic
static int GetCount()
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4425Classes
Static members Example
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
class People public
People()hellip
static int GetPopulation()private
hellip static int population
peopleh
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
Initint Peoplepopulation = 0
PeoplePeople()name(ldquoguyrdquo)step_count(0) population++
People~People() population--
int PeopleGetPopulation() return population
peoplecpp
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
int main() People joestdcout ltlt
PeopleGetPopulation()hellip
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4426Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4427Standard Template Library (STL)
Template A way of making functions or classes more abstract Focus on the behaviour of the function (or the class) without knowing variables data type
A single function class implementation to cover several data type cases
Avoid code replications (simply due to variables data type) Data type resolution performed at compileshytime
Compilers generate additional code Large use of template may strongly increase the executable size Longer compilation times
Debugging is complicated by hard to read compiler messages
Template code is commonly placed in header files Modify a template class may lead to entire project reshybuild
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4428Standard Template Library (STL)
Template functions Example of global function performing addition between two variables of a generic type
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
hellip templateltclass TgtT add(T a1 T a2) return a1 + a2hellip int main()
int i1 i2float f1 f2hellip cout ltlt addltintgt(i1 i2)
ltlt endlcout ltlt addltfloatgt(f1 f2)
ltlt endlreturn 0
The compiler will generatetwo versions of function add()
int add(int a1 int a2) return a1 + a2
int add(int a1 int a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
float add(float a1 float a2) return a1 + a2
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4429Standard Template Library (STL)
Template classes A class including generic type members
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
ifndef MATH_H_define MATH_H_namespace aos
template ltclass Tgtclass Math public
T add(T a1 T a2)T mul(T m1 T m2)T div(T m1 T m2)
namespace aosendif MATH_H_
mathh
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
include mathhnamespace aos
template ltclass TgtT MathltTgtadd(T a1 T a2)
return a1 + a2template ltclass TgtT MathltTgtmul(T m1 T m2)
return m1 m2template ltclass TgtT MathltTgtdiv(T d1 T d2)
return d1 d2template class Mathltintgttemplate class Mathltfloatgt namespace aos
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4430Standard Template Library (STL)
Template classes A class including generic type members
Two instances are used to work on integer and floating points data
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
include ltiostreamgtinclude mathhusing namespace std
int main() aosMathltintgt mIaosMathltfloatgt mF Integer operationscout ltlt Add ltlt mIadd(6 10) ltlt endlcout ltlt Mul ltlt mImul(12 2) ltlt endlcout ltlt Div ltlt mIdiv(7 3) ltlt endl Floating point operationscout ltlt Div ltlt mFdiv(7 3) ltlt endlreturn 0
Add 16Mul 24Div 2Div 233333
Add 16Mul 24Div 2Div 233333
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4431Standard Template Library (STL)
STL A powerful set of C++ template classes Provides generalshypurpose templateshybased classes and functions Implement commonly used algorithms and data structure Containers are the most noticeable example of data structures
List queues stack map set hellip
Used to manage a collection of object of a certain class
The differ for functionality typology (sequential associative unordered) and complexity of accessing and manipulation operations
Iterators are used to step through the elements of the containers Algorithms includes function manipulating containers
Search copy sort transform
For a complete list httpwwwcpluspluscomreferencestl
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4432Standard Template Library (STL)
vector Sequence containers representing dynamic arrays (mutable size)
Contiguous of storage of elements with random access
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)vectorltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorvectorltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlcout ltlt ldquoCitizen 1 isrdquo ltlt citizens[1]GetName() ltlt endlreturn 0
Name JohnName ClaireCitizen 1 is Claire
Name JohnName ClaireCitizen 1 is Claire
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4433Standard Template Library (STL)
list Sequence containers implementing doubleshylinked lists
Constant time insert and erase operations on the object collection
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
int main() People claire(Claire)People john(John)listltPeoplegt citizens Container of Peoplecitizenspush_back(john) Add to vectorcitizenspush_back(claire) Add to vectorlistltPeoplegtiterator itfor(it = citizensbegin() it = citizensend() ++it)
cout ltlt Name ltlt it-gtGetName() ltlt endlreturn 0
Name JohnName Claire
Name JohnName Claire
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4434Outline
C++ Programs Memory allocation Passing parameters to functions
Classes Constructors and assignments Object pointers Qualifiers
Standard Template Library (STL) Templates Example vectorltgt listltgt
Memory management From raw to smart pointers
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4435Memory management
Raw pointers Using (raw) pointers is a powerful CC++ feature but in general difficult to handle and errorshyprone
Consider the following example
This ends in a ldquoSegmentation faultrdquo since ldquoalexrdquo is deallocated multiple times
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
int main() People joe = new People(ldquoJoerdquo)People ann = new People(ldquoAnnrdquo)People alex = new People(ldquoAlexrdquo)joe-gtSetChild(alex)ann-gtSetChild(alex)
delete joedelete anndelete alexreturn 0
class People public
virtual ~People()void SetChild(
People _child)private
People child
class People public
virtual ~People()void SetChild(
People _child)private
People child
People~People() delete child
People~People() delete child
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4436Memory management
Smart pointers To solve the problem we should start from the concept of ownership To own a dynamically allocated object means to be the entity in charge of deallocating it
Smart pointers is a feature introduced in C++ since standard C++11 to simplify the memory management in C++ programs
Concept of ownership introduced and exploited
Limited garbage collection facilities Base idea To wrap raw pointers in stack allocated objects that could control the lifeshycycle of the dynamically allocated object
We are going to focus on just two class of smart pointerUnique pointers (class unique_ptrltgt)
Shared pointers (class shared_ptrltgt)
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4437Memory management
Shared pointers Pointers of type shared allows us to keep track of the number of shared ownership ie references to the objects
Reference counting based mechanismAssignments and scope exit alter the reference counters
If the count is decreased to zero the object is automatically deallocated This facility does not come for free
Reference counting mechanism requires a little additional memory overhead
Shared pointers can rely the developer from the burden of using explicit newdelete constructs
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)hellip
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4438Memory management
Shared pointers Similarly to pointer variables
Object ldquojackrdquo (of class shared_ptrltgt) is allocated onto the stack
Members of the pointed object are accessed by using the ldquo-gtrdquo operator shared_ptrltgt member function get()returns the raw pointer value
Using ldquordquo operator to access shared_ptrltgt member functions
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
hellip shared_ptrltPeoplegt jack
= make_sharedltPeoplegt(Jack) cout ltlt Name = ltlt jack-gtGetName() ltlt endl cout ltlt Raw ptr = ltlt jackget() ltlt endl hellip
Name = JackRaw pointer = 0x22440c8
Name = JackRaw pointer = 0x22440c8
mainjack
0x22440c8
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4439Memory management
Shared pointers Example an assignment operation and a scope exit
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
include ltmemorygtusing namespace stdint main()
hellip shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
shared_ptrltPeoplegt jack2jack2 = jackcout ltlt Jack refcount = ltlt jackuse_count() ltlt endl
cout ltlt Jack refcount = ltlt jackuse_count() ltlt endl return 0
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Jack refcount = 1Jack refcount = 2 jack2 = jackJack refcount = 1 jack2 out of scope =gt jack refcount decreaseJack im dying People object ldquoJackrdquo destruction
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4440Memory management
Shared pointers The previous ldquoparentsrdquo example can be rewritten as follows using shared pointers (changing also SetChild() signature)
No need of explicit delete (objects deallocated at main function exit) No multiple deallocation thanks to reference counting
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
include ltmemorygtusing namespace stdint main()
shared_ptrltPeoplegt jack = make_sharedltPeoplegt(Jack)shared_ptrltPeoplegt ann = make_sharedltPeoplegt(Ann)shared_ptrltPeoplegt alex = make_sharedltPeoplegt(Alex)jack-gtSetChild(alex)ann-gtSetChild(alex)return 0
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4441Memory management
Unique pointers Do not share the ownership of a pointed object
Unique pointer means unique ownership
Only one object responsible of memory deallocation Copy assignments not allowed only move assignments are
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
include ltmemorygtusing namespace stdint main()
unique_ptrltPeoplegt jason(new People(Jason))unique_ptrltPeoplegt lauracout ltlt Jason = ltlt jasonget() ltlt endl laura = stdmove(jason)cout ltlt Jason = ltlt jasonget() ltlt endl cout ltlt Laura = ltlt lauraget() ltlt endl
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Jason = 0x15fd040Jason = 0Laura = 0x15fd040
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4442Memory management
Objects and containers Containers can be used to store objects (stack allocated)
An object copy is performed when a new object is added to the collection Containers can be used to store pointers to objects (heap allocated)
For dynamically allocated objects keep in mind the potential pitfalls about memory management
clear() calls objects destructors but what about raw pointers
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
int main() vectorltPeople gt citizens Using raw pointersPeople p1 = new People(p1)People p2 = new People(p2)citizenspush_back(p1)citizenspush_back(p2)citizensclear() Clear the containerreturn 0
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4443Memory management
Objects and containers We may used smart (eg shared) pointers also in containers
Insertremove operations affect shared pointers reference counting Destroying the vector the reference counters are decreased
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
int main() vectorltshared_ptrltPeoplegtgt citizens Using shared pointersshared_ptrltPeoplegt p1 = make_sharedltPeoplegt(p1)shared_ptrltPeoplegt p2 = make_sharedltPeoplegt(p2)citizenspush_back(p1)citizenspush_back(p2)cout ltlt p1 use count = ltlt p1use_count() ltlt endlreturn 0
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
p1 use count = 2p1 im dyingp2 im dyingp3 im dying
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm
Advanced Operating SystemsGiuseppe Massari
4444References
Web links httpwwwcpluspluscom httpencppreferencecomw httpwwwhorstmanncomccj2ccjapp3html httpwwwcprogrammingcomtutorialconstructor_destructor_orderinghtml
httpwwwyolinuxcomTUTORIALSC++MemoryCorruptionAndMemoryLeakshtml
httpduramechocomComputerInformationWhyHowCppConsthtml
httpwwwtutorialspointcomcpluspluscpp_stl_tutorialhtm