Skip to content

Commit

Permalink
fix: memory leaks using unique_ptr
Browse files Browse the repository at this point in the history
  • Loading branch information
midouest committed Feb 26, 2021
1 parent 4265bde commit b48c84e
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 118 deletions.
15 changes: 6 additions & 9 deletions include/expression.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <string>
#include <memory>

using namespace std;

Expand All @@ -14,6 +15,8 @@ namespace bb
virtual string to_string() const = 0;
};

using ExpressionPtr = unique_ptr<Expression>;

class Variable : public Expression
{
public:
Expand Down Expand Up @@ -50,13 +53,7 @@ namespace bb
class BinaryExpression : public Expression
{
public:
explicit BinaryExpression(Expression *left, Expression *right) : left(left), right(right){};

~BinaryExpression()
{
delete left;
delete right;
}
explicit BinaryExpression(ExpressionPtr left, ExpressionPtr right) : left(move(left)), right(move(right)){};

string to_string() const
{
Expand All @@ -66,8 +63,8 @@ namespace bb
protected:
virtual string operand() const = 0;

Expression *left;
Expression *right;
ExpressionPtr left;
ExpressionPtr right;
};

class Add : public BinaryExpression
Expand Down
2 changes: 1 addition & 1 deletion include/parse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ using namespace std;

namespace bb
{
Expression *parse(string &input);
ExpressionPtr parse(string &input);
}
9 changes: 1 addition & 8 deletions plugins/ByteBeat/ByteBeat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,7 @@ namespace ByteBeat
// 8-bit unsigned integers, then transformed to floats with a range of
// +/-1.0. An expression that emits a constant value of 128 will
// correspond roughly to 0.0 at the output.
mExpression = new bb::Constant(128);
}

ByteBeat::~ByteBeat()
{
delete mExpression;
mExpression = bb::ExpressionPtr(new bb::Constant(128));
}

void ByteBeat::parse(const char *input)
Expand All @@ -35,9 +30,7 @@ namespace ByteBeat

try
{
bb::Expression *prevExpr = mExpression;
mExpression = bb::parse(s);
delete prevExpr;
}
catch (invalid_argument &ex)
{
Expand Down
3 changes: 1 addition & 2 deletions plugins/ByteBeat/ByteBeat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ namespace ByteBeat
{
public:
ByteBeat();
~ByteBeat();

/**
* Parse the incoming expression and replace the existing expression.
Expand All @@ -42,6 +41,6 @@ namespace ByteBeat
int mPrevT = 0;

/** bytebeat expression used to generate audio samples */
bb::Expression *mExpression;
bb::ExpressionPtr mExpression;
};
}
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ int main(int argc, char *argv[])
}

string input{argv[1]};
Expression *expr;
ExpressionPtr expr;
try
{
expr = parse(input);
Expand Down
80 changes: 40 additions & 40 deletions src/parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ namespace bb
{
using TokenIter = vector<string>::iterator;

Expression *parse_expression(TokenIter &it, TokenIter &end);
Expression *parse_expression_inner(TokenIter &it,
TokenIter &end,
Expression *lhs,
int min_precedence);
Expression *parse_primary(TokenIter &it, TokenIter &end);
ExpressionPtr parse_expression(TokenIter &it, TokenIter &end);
ExpressionPtr parse_expression_inner(TokenIter &it,
TokenIter &end,
ExpressionPtr lhs,
int min_precedence);
ExpressionPtr parse_primary(TokenIter &it, TokenIter &end);

int get_precedence(string &token);
Expression *make_binary_op(string &op, Expression *lhs, Expression *rhs);
ExpressionPtr make_binary_op(string &op, ExpressionPtr lhs, ExpressionPtr rhs);

Expression *parse(string &input)
ExpressionPtr parse(string &input)
{
vector<string> tokens = tokenize(input);
if (tokens.empty())
Expand All @@ -27,7 +27,7 @@ namespace bb

auto it = tokens.begin();
auto end = tokens.end();
Expression *expr = parse_expression(it, end);
ExpressionPtr expr = parse_expression(it, end);
if (it != tokens.end())
{
throw invalid_argument("not all tokens consumed");
Expand All @@ -36,16 +36,16 @@ namespace bb
return expr;
}

Expression *parse_expression(TokenIter &it, TokenIter &end)
ExpressionPtr parse_expression(TokenIter &it, TokenIter &end)
{
Expression *lhs = parse_primary(it, end);
return parse_expression_inner(it, end, lhs, 0);
ExpressionPtr lhs = parse_primary(it, end);
return parse_expression_inner(it, end, move(lhs), 0);
}

Expression *parse_expression_inner(TokenIter &it,
TokenIter &end,
Expression *lhs,
int min_precedence)
ExpressionPtr parse_expression_inner(TokenIter &it,
TokenIter &end,
ExpressionPtr lhs,
int min_precedence)
{
if (it == end)
{
Expand All @@ -60,18 +60,18 @@ namespace bb
string op = lookahead;
++it;

Expression *rhs = parse_primary(it, end);
ExpressionPtr rhs = parse_primary(it, end);
if (it == end)
{
return make_binary_op(op, lhs, rhs);
return make_binary_op(op, move(lhs), move(rhs));
}

lookahead = *it;
int next_precedence = get_precedence(lookahead);

while (next_precedence > precedence)
{
rhs = parse_expression_inner(it, end, rhs, next_precedence);
rhs = parse_expression_inner(it, end, move(rhs), next_precedence);
if (it == end)
{
next_precedence = -1;
Expand All @@ -83,13 +83,13 @@ namespace bb
}

precedence = next_precedence;
lhs = make_binary_op(op, lhs, rhs);
lhs = make_binary_op(op, move(lhs), move(rhs));
}

return lhs;
}

Expression *parse_primary(TokenIter &it, TokenIter &end)
ExpressionPtr parse_primary(TokenIter &it, TokenIter &end)
{
if (it == end)
{
Expand All @@ -101,7 +101,7 @@ namespace bb
if (token == "t")
{
++it;
return new Variable();
return ExpressionPtr(new Variable());
}

if (token == "(")
Expand All @@ -120,7 +120,7 @@ namespace bb
{
int n = stoi(token);
++it;
return new Constant(n);
return ExpressionPtr(new Constant(n));
}
catch (invalid_argument &ex)
{
Expand Down Expand Up @@ -166,86 +166,86 @@ namespace bb
return -1;
}

Expression *make_binary_op(std::string &op, Expression *lhs, Expression *rhs)
ExpressionPtr make_binary_op(std::string &op, ExpressionPtr lhs, ExpressionPtr rhs)
{
if (op == "+")
{
return new Add(lhs, rhs);
return ExpressionPtr(new Add(move(lhs), move(rhs)));
}

if (op == "-")
{
return new Subtract(lhs, rhs);
return ExpressionPtr(new Subtract(move(lhs), move(rhs)));
}

if (op == "*")
{
return new Multiply(lhs, rhs);
return ExpressionPtr(new Multiply(move(lhs), move(rhs)));
}

if (op == "/")
{
return new Divide(lhs, rhs);
return ExpressionPtr(new Divide(move(lhs), move(rhs)));
}

if (op == "%")
{
return new Modulo(lhs, rhs);
return ExpressionPtr(new Modulo(move(lhs), move(rhs)));
}

if (op == "&")
{
return new BitwiseAnd(lhs, rhs);
return ExpressionPtr(new BitwiseAnd(move(lhs), move(rhs)));
}

if (op == "|")
{
return new BitwiseOr(lhs, rhs);
return ExpressionPtr(new BitwiseOr(move(lhs), move(rhs)));
}

if (op == "^")
{
return new BitwiseXor(lhs, rhs);
return ExpressionPtr(new BitwiseXor(move(lhs), move(rhs)));
}

if (op == "<<")
{
return new BitwiseShiftLeft(lhs, rhs);
return ExpressionPtr(new BitwiseShiftLeft(move(lhs), move(rhs)));
}

if (op == ">>")
{
return new BitwiseShiftRight(lhs, rhs);
return ExpressionPtr(new BitwiseShiftRight(move(lhs), move(rhs)));
}

if (op == "<")
{
return new LessThan(lhs, rhs);
return ExpressionPtr(new LessThan(move(lhs), move(rhs)));
}

if (op == ">")
{
return new GreaterThan(lhs, rhs);
return ExpressionPtr(new GreaterThan(move(lhs), move(rhs)));
}

if (op == "<=")
{
return new LessThanOrEqual(lhs, rhs);
return ExpressionPtr(new LessThanOrEqual(move(lhs), move(rhs)));
}

if (op == ">=")
{
return new GreaterThanOrEqual(lhs, rhs);
return ExpressionPtr(new GreaterThanOrEqual(move(lhs), move(rhs)));
}

if (op == "==")
{
return new Equal(lhs, rhs);
return ExpressionPtr(new Equal(move(lhs), move(rhs)));
}

if (op == "!=")
{
return new NotEqual(lhs, rhs);
return ExpressionPtr(new NotEqual(move(lhs), move(rhs)));
}

throw invalid_argument("unrecognized operator");
Expand Down
Loading

0 comments on commit b48c84e

Please sign in to comment.