Understanding the MemBot Project
Udacity C++ Memory Management — Project Walkthrough (Part 1)
Understanding the MemBot Project
Udacity C++ Memory Management — Project Walkthrough (Part 1)
MemBot project is part of Udacity’s C++ Memory Management course. At first glance, it looks like a chatbot project. But in reality, this is not an AI project. This project is about memory ownership, object lifetime, and move semantics in C++.
The chatbot logic itself is already implemented in the project template. The real job is to:
- Understand who owns what
- Decide where memory should live
- Make sure objects are moved, not copied
- Prevent memory leaks and double deletes
I’m writing this post as a study recap, because you cannot safely write modern C++ unless you fully understand the existing structure.
High-Level Concept: What is MemBot?
MemBot works by navigating a knowledge graph.
Core idea
- Each GraphNode contains chatbot answers
- Each GraphEdge represents a transition between answers
- The ChatBot moves from node to node based on user input
Think of like this:
User Input
↓
ChatBot
↓
GraphNode (current answer)
↓
GraphEdge (matched by keyword)
↓
Next GraphNode
This design allows us to practice pointer ownership and move semantics in a realistic object graph.
Project Structure Overview
Here are the most important source files:
src/
├── chatbot.cpp / chatbot.h
├── chatlogic.cpp / chatlogic.h
├── graphnode.cpp / graphnode.h
├── graphedge.cpp / graphedge.h
└── main_cli.cpp
Let’s quickly define responsibilities before diving deeper.
- ChatBot: Represents the chatbot agent
- ChatLogic: Loads graph, manages overall flow
- GraphNode: Stores answers and edges
- GraphEdge: Connects nodes using keywords
- main_cli: Starts terminal interaction
The Knowledge Graph (Big Picture)
The chatbot’s “brain” is stored in a text file, which looks like this:
<TYPE:NODE><ID:0><ANSWER:Hello, my name is MemBot>
<TYPE:NODE><ID:1><ANSWER:Let’s talk about memory>
<TYPE:EDGE><ID:0><PARENT:0><CHILD:1><KEYWORD:memory>
This gets converted into a graph in memory:
+---------+ Edge (keyword: memory) +---------+
| Node 0 | ------------------------------> | Node 1 |
| Answer | | Answer |
+---------+ +---------+
Nodes do not own each other, edges connect nodes, and ownership flows downward. This is crucial later when we apply smart pointers.
ChatBot Class — The “Traveler”
ChatBot receives messages from the user, asks ChatLogic to send responses and moves between nodes using move semantics. It does not own the graph, delete nodes, or create edges. That is, ChatBot does not own anything here. It only points to existing objects. This avoids circular ownership and keeps lifetimes simple.
class ChatBot {
private:
GraphNode *_currentNode; // not owned
GraphNode *_rootNode; // not owned
ChatLogic *_chatLogic; // not owned
};
Rule of Five (Why It Matters Here)
The ChatBot class implements the Rule of Five:
- Destructor
- Copy constructor
- Copy assignment
- Move constructor
- Move assignment
Each function prints a message like:
>>> Rule of Five Component: ChatBot Move Constructor <<<
Why is this useful?
Because later, when the ChatBot moves between nodes, you can visually confirm:
- Was it copied? -> Copying would be dangerous
- Or was it moved? -> Moving is safe and intended
ChatLogic — The Graph Manager
ChatLogic is the central controller. What ChatLogic does?
- Reads the file
- Creates all nodes and edges
- Identifies the root node
- Connects the ChatBot to the graph
- Sends messages between ChatBot and UI
class ChatLogic {
private:
std::vector<GraphNode *> _nodes; // owns nodes
GraphNode *_currentNode; // not owned
ChatBot *_chatBot; // not owned
};
Ownership rule
- ChatLogic owns all GraphNodes
- ChatLogic does NOT own ChatBot
- ChatLogic does NOT own edges directly (this changes later)
This design prevents double deletion and centralizes graph creation.
GraphNode— The Answer Holder
Each GraphNode contains:
- A list of answers
- Edges to parent nodes (incoming)
- Edges to child nodes (outgoing)
- Possibly the ChatBot (temporarily)
class GraphNode {
private:
std::vector<GraphEdge*> _childEdges; // outgoing
std::vector<GraphEdge*> _parentEdges; // incoming
ChatBot *_chatBot; // not owned
};
Why this structure?
- Nodes must know where they can go next
- Nodes must know who can lead to them
- Only one node at a time holds the ChatBot
Later, this class will enforce exclusive ownership of outgoing edges.
GraphEdge — The Connector
GraphEdge represents possible transitions.
What an edge contains?
- Parent node (non-owning)
- Child node (non-owning)
- Keywords used for matching
- Edge ID
class GraphEdge {
private:
GraphNode *_parentNode; // not owned
GraphNode *_childNode; // not owned
std::vector<std::string> _keywords;
};
Edges do not own nodes. Nodes will eventually own edges. This avoids circular ownership like:
Node owns Edge
Edge owns Node ❌ (bad)
Memory Ownership Map (So Far)
Here’s the big picture.
ChatLogic
├── owns → GraphNode 0
│ ├── outgoing → GraphEdge 0
│ └── incoming ← none
├── owns → GraphNode 1
│ ├── incoming ← GraphEdge 0
│ └── outgoing → ...
└── references → ChatBot
ChatBot:
ChatBot
├── currentNode (pointer)
├── rootNode (pointer)
└── chatLogic (pointer)
No cycles. No ambiguity. Clean ownership.
What we are NOT Required to Understand
At this point, we do NOT need to deeply understand:
- Levenshtein distance implementation
- Keyword matching logic
- NLP-style decision making
Those parts already work. The project is focused on memory correctness, not chatbot intelligence.
Instead, youshould understand:
- Why ownership matters
- Why move semantics are required
- Why raw pointers are still used in some places
- Where smart pointers make sense
If you don’t, you’ll end up with:
- Dangling pointers
- Double deletes
- Segmentation faults
In Part 2, we will:
- Redesign ownership using
unique_ptr - Explain incoming & outgoing edge ownership
- Show how ChatBot moves between nodes
- Add move semantics diagrams
Once Part 2 is done, filling TODOs will feel not scary :)
메타데이터
- post_id
- ddfdad7affab
- slug
- understanding-the-membot-project-ddfdad7affab
- url
- https://medium.com/@su-paris/understanding-the-membot-project-ddfdad7affab
- canonical_url
- https://medium.com/@su-paris/understanding-the-membot-project-ddfdad7affab
- author_url
- https://medium.com/@su-paris
- status
- ok
- fetched_at
- 2026-07-13 09:35:19