Fix memory leaks, fix tests.
authorRafał Długołęcki <rafal@dlugolecki.net.pl>
Tue, 5 May 2015 21:08:01 +0000 (23:08 +0200)
committerRafał Długołęcki <rafal@dlugolecki.net.pl>
Tue, 5 May 2015 21:08:01 +0000 (23:08 +0200)
include/argument.h
include/callable.h
include/command.h
include/descriptive.h
include/option.h
include/parameter.h

index 53dea343344e8b3b1bf42ab301551135eb9d33c0..b07ae67080925875a3a039218288640f31680bd7 100644 (file)
@@ -25,7 +25,7 @@ namespace command {
         /** Variable indicating if current Argument was already used or not */
         bool used = false;
 
-        ArgumentType argument;
+        ArgumentType value;
     public:
         typedef class Argument Type;
 
@@ -48,7 +48,7 @@ namespace command {
          *
          */
         virtual void handle() {
-            this->call(argument);
+            this->call(value);
         }
 
         /**
@@ -72,7 +72,7 @@ namespace command {
                 std::stringstream ss;
 
                 ss << argv;
-                ss >> argument;
+                ss >> value;
 
                 if (!ss.fail()) {
                     used = true;
index bf74377de5ebe5e7823cefdaf873adfb9e2a3953..544b37115fb2cbe4b756ae1bb10f439812c76c8b 100644 (file)
@@ -24,6 +24,7 @@ namespace command {
         Callable(void (*function)(ArgumentType))
             : func(function) {
         }
+
         virtual ~Callable() { }
 
     protected:
index ec0868180b94a2c7f29121a6e7b264b82f6c7c53..8ecb280e78aff6bb4080c40fd2ae086f65b44f12 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <string>
 #include <vector>
-#include <iostream>
 
 #include "parameter.h"
 
@@ -26,16 +25,20 @@ namespace command {
         Command(unsigned int argc, char *argv[], std::initializer_list<Parameter *> params)
             : parameters(params) {
 
-            matchArguments(argc, argv);
+            try {
+                matchArguments(argc, argv);
+            }
+            catch(std::invalid_argument exception) {
+                releaseMemory();
+                throw;
+            }
         }
 
         /**
          * Destructor. Releases allocated memory.
          */
         ~Command() {
-            for (Parameter * parameter : parameters) {
-                delete parameter;
-            }
+            releaseMemory();
         }
     protected:
         /**
@@ -51,6 +54,19 @@ namespace command {
                 }
             }
         }
+
+        /**
+         * Releases acquired memory
+         */
+        void releaseMemory() {
+            for (Parameter * parameter : parameters) {
+                if (parameter != NULL) {
+                    delete parameter;
+                }
+            }
+            parameters.clear();
+            parameters.shrink_to_fit();
+        }
     };
 }
 
index 08be41e8be3638613191c17d4515c70bf9591d47..33f62fdbdcf40363e441c122e6364f81aede92e4 100644 (file)
@@ -8,7 +8,7 @@ namespace command {
      * Descriptive behaviour class.
      */
     class Descriptive {
-        std::string description;
+        const std::string description;
     public:
         /**
          * Default constructor.
@@ -19,12 +19,14 @@ namespace command {
             : description(description) {
         }
 
+        virtual ~Descriptive() { }
+
         /**
          * Returns description of the current class.
          *
          * @return provided description for the class
          */
-        std::string describe() {
+        const std::string & describe() {
             return description;
         }
     };
index a77d8f446d19f179b9799ae5f7393d23c4240042..115676665388a3fb88f42ce065bde8ae85bf4b39 100644 (file)
@@ -26,7 +26,7 @@ namespace command {
         /**
          * Current Option name
          */
-        OptionName name;
+        const OptionName name;
 
         /**
          * Current Option value
@@ -44,7 +44,7 @@ namespace command {
          * @param description Description of current Option
          * @param function Function used to handle current Option.
          */
-        Option(std::string name, const std::string & description, void (*function)(OptionType))
+        Option(const std::string & name, const std::string & description, void (*function)(OptionType))
             : Parameter(description), Callable<OptionType>(function), name(name) {
         }
 
@@ -87,18 +87,21 @@ namespace command {
          * @throw std::invalid_argument when OptionValue part failed conversion
          *  to OptionType
          */
-        virtual bool understand(const std::string & argv) {
-            if ((!used) &&
-                (argv.find(name) == 0)) {
+        virtual bool understand(const std::string & argv)
+            throw(std::invalid_argument) {
+
+            if ((!used) && (argv.find(name) == 0)) {
                 std::size_t pos = argv.find("=");
+
                 if (pos != name.size()) {
                     throw std::invalid_argument("Option: " + name + " requires value but no one has been provided");
                 }
 
                 std::stringstream ss;
-
                 ss << argv.substr(pos + 1);
-                ss >> value;
+                ss >> value;// memory leak? when is uncommented, and exception is
+                            // thrown, valgrind shows e.g.:
+                            //  possibly lost: 380 bytes in 7 blocks
 
                 if (ss.fail()) {
                     throw std::invalid_argument("Value for option: " + name + " failed conversion to the required type");
@@ -132,7 +135,7 @@ namespace command {
         /**
          * Current Option name
          */
-        OptionName name;
+        const OptionName name;
 
         /** Variable indicating if current Option was already used or not */
         bool used = false;
@@ -145,15 +148,10 @@ namespace command {
          * @param description Description of current Option
          * @param function Function used to handle current Option.
          */
-        Option(std::string name, const std::string & description, void (*function)(void))
+        Option(const std::string & name, const std::string & description, void (*function)(void))
             : Parameter(description), Callable<void>(function), name(name) {
         }
 
-        /**
-         *
-         */
-        virtual ~Option() { }
-
         /**
          *
          */
index a96128c407e50f226d417a8ac5b811cf3944eb7a..1396f830d07ed3d63f11eb9540f6bc028a71c4cd 100644 (file)
@@ -24,7 +24,8 @@ namespace command {
         Parameter(const std::string & description)
             : Descriptive(description) {
         }
-        virtual ~Parameter() {}
+
+        virtual ~Parameter() { }
 
         /**
          * Method used for handling method calls linked with Argument or Option