Reputation: 2299
I'm working on a project for a class where we are supposed to implement basic functionality for a text editor, including undo and redo. I currently have my undo/redo functions working correctly, the only problem is, is that I'm getting a valgrind error when trying to free the memory from a Command
object that tells us what to execute.
This Command
object is part of a struct within a namespace like so:
struct UserInteraction
{
UserInteractionType type;
Command* command;
};
Currently, I store each command that the user issues in a std::vector of type <UserInteraction>
called undoStack
. I also have a redoStack
of the same type which is also a std::vector. Storing each command looks like this:
else if (interaction.type == UserInteractionType::command) // COMMAND
{
try
{
interaction.command->execute(editor);
commandInteraction = true;
undoStack.push_back(interaction);
view.clearErrorMessage();
}
catch (EditorException& e)
{
delete interaction.command;
view.showErrorMessage(e.getReason());
}
view.refresh();
} // end if-else
I need to deallocate each UserInteraction that was pushed into the vector, when the user presses ctrl+x (which exits the program). Otherwise, any command I issue gives me a error like this:
4 bytes in 1 blocks are definitely lost in loss record 2 of 38
Where each command entered increases the amount of bytes by lost by 4.
I figured I just needed to deallocate all the memory used by each vector within the quit command, but all the current solutions that people use seem to still give me memory leaks. Here are two versions of my quit method (both of which still give me memory leaks):
First try:
if (interaction.type == UserInteractionType::quit)
{
clear undo
std::vector<UserInteraction>().swap(undoStack);
clear redo
std::vector<UserInteraction>().swap(redoStack);
break;
}
And my second try at deallocating memory:
if (interaction.type == UserInteractionType::quit)
{
undoStack.clear();
undoStack.shrink_to_fit();
redoStack.clear();
redoStack.shrink_to_fit();
break;
}
So how can I actually deallocate everything in both vectors?
Upvotes: 1
Views: 219
Reputation: 21156
By freeing the memory of your vector, you'll only destroy your UserInteractions, but not the commands they are pointing to. If you use a c++11 compiler you can use a smart pointer.
struct UserInteraction
{
UserInteractionType type;
std::unique_ptr<Command> command;
// or
std::shared_ptr<Command> command;
};
That will automatically take care of deleting the commands. If not, I`d just delete all the commands in a loop iterating through the vector elements. (You could also write a costum destructor that deletes the command, together with a copy-assignment operator and -ctor (deep copy), as well as move-assignment operator and -ctor, but that seems like an overly complex solution)
Upvotes: 1