This is the project for the third course in the Udacity C++ Nanodegree Program: Memory Management.
The ChatBot code creates a dialogue where users can ask questions about some aspects of memory management in C++. After the knowledge base of the chatbot has been loaded from a text file, a knowledge graph representation is created in computer memory, where chatbot answers represent the graph nodes and user queries represent the graph edges. After a user query has been sent to the chatbot, the Levenshtein distance is used to identify the most probable answer. The code is fully functional as-is and uses raw pointers to represent the knowledge graph and interconnections between objects throughout the project.
In this project I have analyzed and modified the program. Although the base code provided by Udacity could be executed and did work as intended, no advanced memory management concepts had been used; there were no smart pointers, no move semantics and not much thought had been given to ownership or memory allocation.
The goal was to use the course knowledge to optimize the ChatBot program from a memory management perspective. There were a total of five specific tasks completed, which are detailed below.
- cmake >= 3.11
- All OSes: click here for installation instructions
- make >= 4.1 (Linux, Mac), 3.81 (Windows)
- Linux: make is installed by default on most Linux distros
- Mac: install Xcode command line tools to get make
- Windows: Click here for installation instructions
- gcc/g++ >= 5.4
- Linux: gcc / g++ is installed by default on most Linux distros
- Mac: same deal as make - install Xcode command line tools
- Windows: recommend using MinGW
- wxWidgets >= 3.0
- Linux:
sudo apt-get install libwxgtk3.0-gtk3-dev libwxgtk3.0-gtk3-0v5
. If you are facing unmet dependency issues, refer to the official page for installing the unmet dependencies. - Mac: There is a homebrew installation available.
- Installation instructions can be found here. Some version numbers may need to be changed in instructions to install v3.0 or greater.
- Linux:
- Clone this repo.
- Make a build directory in the top level directory:
mkdir build && cd build
- Compile:
cmake .. && make
- Run it:
./membot
.
Initially, the program crashed when you closed the window. There was a small bug hidden somewhere, which had something to do with improper memory management. So the first warm-up task was to find this bug and remove it.
Aside from the bug mentioned above, there were five additional major tasks in the Memory Management chatbot project, which are:
In file chatgui.h
/ chatgui.cpp
, make _chatLogic
an exclusive resource to class ChatbotPanelDialog
using an appropriate smart pointer. Where required, make changes to the code such that data structures and function parameters reflect the new structure.
In file chatbot.h
/ chatbot.cpp
, make changes to the class ChatBot
such that it complies with the Rule of Five. Make sure to properly allocate / deallocate memory resources on the heap and also copy member data where it makes sense to you. In each of the methods (e.g. the copy constructor), print a string of the type "ChatBot Copy Constructor" to the console so that you can see which method is called in later examples.
In file chatlogic.h
/ chatlogic.cpp
, adapt the vector _nodes
in a way that the instances of GraphNodes
to which the vector elements refer are exclusively owned by the class ChatLogic
. Use an appropriate type of smart pointer to achieve this. Where required, make changes to the code such that data structures and function parameters reflect the changes. When passing the GraphNode
instances to functions, make sure to not transfer ownership and try to contain the changes to class ChatLogic
where possible.
In files chatlogic.h
/ chatlogic.cpp
and graphnode.h
/ graphnode.cpp
change the ownership of all instances of GraphEdge
in a way such that each instance of GraphNode
exclusively owns the outgoing GraphEdges
and holds non-owning references to incoming GraphEdges
. Use appropriate smart pointers and where required, make changes to the code such that data structures and function parameters reflect the changes. When transferring ownership from class ChatLogic
, where all instances of GraphEdge
are created, into instances of GraphNode
, make sure to use move semantics.
In file chatlogic.cpp
, create a local ChatBot
instance on the stack at the bottom of function LoadAnswerGraphFromFile
. Then, use move semantics to pass the ChatBot
instance into the root node. Make sure that ChatLogic
has no ownership relation to the ChatBot
instance and thus is no longer responsible for memory allocation and deallocation. Note that the member _chatBot
of ChatLogic
remains so it can be used as a communication handle between GUI and ChatBot
instance. Make all required changes in files chatlogic.h
/ chatlogic.cpp
and graphnode.h
/ graphnode.cpp
. When the program is executed, messages on which part of the Rule of Five components of ChatBot
is called should be printed to the console. When sending a query to the ChatBot
, the output should look like the following:
ChatBot Constructor
ChatBot Move Constructor
ChatBot Move Assignment Operator
ChatBot Destructor
ChatBot Destructor