opencv_trail_effect.cpp: fix potential leak when exiting during option parsing
authorAntonio Ospite <ao2@ao2.it>
Sat, 10 Oct 2020 17:38:10 +0000 (19:38 +0200)
committerAntonio Ospite <ao2@ao2.it>
Sat, 10 Oct 2020 17:38:10 +0000 (19:38 +0200)
When bailing out during option parsingi, for example when '-h' or an
invalid option is passed, some pointer to strings were not cleaned up,
leading to a potential leak, as reported by scan-build:

-----------------------------------------------------------------------
opencv_trail_effect.cpp:120:4: warning: Potential leak of memory pointed to by 'drawing_method'
                        usage(argv[0]);
                        ^~~~~
opencv_trail_effect.cpp:120:4: warning: Potential leak of memory pointed to by 'input_file'
                        usage(argv[0]);
                        ^~~~~
opencv_trail_effect.cpp:120:4: warning: Potential leak of memory pointed to by 'output_file'
                        usage(argv[0]);
                        ^~~~~
opencv_trail_effect.cpp:120:4: warning: Potential leak of memory pointed to by 'segmentation_method'
                        usage(argv[0]);
                        ^~~~~
opencv_trail_effect.cpp:123:4: warning: Potential leak of memory pointed to by 'drawing_method'
                        usage(argv[0]);
                        ^~~~~
opencv_trail_effect.cpp:123:4: warning: Potential leak of memory pointed to by 'segmentation_method'
                        usage(argv[0]);
                        ^~~~~
-----------------------------------------------------------------------

Stop using pointers to strings which really give no benefits in this
case and avoid the issue altogether.

opencv_trail_effect.cpp

index 357cc42..bc5b187 100644 (file)
@@ -71,13 +71,13 @@ int main(int argc, char *argv[])
        int ret = 0;
        int opt;
 
-       std::string *input_file = NULL;
-       std::string *output_file = NULL;
+       std::string input_file;
+       std::string output_file;
        int trail_lenght = 25;
-       std::string *segmentation_method = new std::string("background");
+       std::string segmentation_method("background");
        int background_learn_frames = 50;
        int threshold_level = 5;
-       std::string *drawing_method = new std::string("copy");
+       std::string drawing_method("copy");
        bool reverse_trail = false;
        bool show_background = false;
        bool redraw_current_frame = false;
@@ -85,17 +85,16 @@ int main(int argc, char *argv[])
        while ((opt = getopt(argc, argv, "i:o:l:s:b:t:d:rBFh")) != -1) {
                switch (opt) {
                case 'i':
-                       input_file = new std::string(optarg);
+                       input_file = std::string(optarg);
                        break;
                case 'o':
-                       output_file = new std::string(optarg);
+                       output_file = std::string(optarg);
                        break;
                case 'l':
                        trail_lenght = atoi(optarg);
                        break;
                case 's':
-                       delete segmentation_method;
-                       segmentation_method = new std::string(optarg);
+                       segmentation_method = std::string(optarg);
                        break;
                case 'b':
                        background_learn_frames = atoi(optarg);
@@ -104,8 +103,7 @@ int main(int argc, char *argv[])
                        threshold_level = atoi(optarg);
                        break;
                case 'd':
-                       delete drawing_method;
-                       drawing_method = new std::string(optarg);
+                       drawing_method = std::string(optarg);
                        break;
                case 'r':
                        reverse_trail = true;
@@ -130,8 +128,8 @@ int main(int argc, char *argv[])
        cv::Size frame_size;
        cv::Mat input_frame;
 
-       if (input_file) {
-               inputVideo.open(*input_file);
+       if (!input_file.empty()) {
+               inputVideo.open(input_file);
        } else {
                inputVideo.open(0);
        }
@@ -145,12 +143,12 @@ int main(int argc, char *argv[])
        frame_size = cv::Size((int) inputVideo.get(cv::CAP_PROP_FRAME_WIDTH),
                              (int) inputVideo.get(cv::CAP_PROP_FRAME_HEIGHT));
 
-       if (output_file) {
+       if (!output_file.empty()) {
                int fps = inputVideo.get(cv::CAP_PROP_FPS);
                if (fps < 0)
                        fps = 25;
 
-               outputVideo.open(*output_file, cv::VideoWriter::fourcc('M','J','P','G'), fps, frame_size, true);
+               outputVideo.open(output_file, cv::VideoWriter::fourcc('M','J','P','G'), fps, frame_size, true);
                if (!outputVideo.isOpened()) {
                        std::cerr  << "Could not open the output video for write." << std::endl;
                        ret = -1;
@@ -166,14 +164,14 @@ int main(int argc, char *argv[])
 
        trail->setRedrawCurrentFrame(redraw_current_frame);
 
-       if (trail->setDrawingMethod(*drawing_method) < 0) {
+       if (trail->setDrawingMethod(drawing_method) < 0) {
                std::cerr  << "Invalid drawing method." << std::endl;
                ret = -1;
                goto out_delete_trail;
        }
 
        Segmentation *segmentation;
-       if (*segmentation_method == "background") {
+       if (segmentation_method == "background") {
                segmentation = new MOG2Segmentation(inputVideo, background_learn_frames);
                if (show_background) {
                        cv::Mat background(frame_size, inputVideo.get(cv::CAP_PROP_FORMAT));
@@ -181,9 +179,9 @@ int main(int argc, char *argv[])
                        ((MOG2Segmentation *)segmentation)->getBackgroundImage(background);
                        trail->setBackground(background);
                }
-       } else if (*segmentation_method == "threshold") {
+       } else if (segmentation_method == "threshold") {
                segmentation = new ThresholdSegmentation(threshold_level);
-       } else if (*segmentation_method == "none") {
+       } else if (segmentation_method == "none") {
                segmentation = new DummySegmentation();
        } else {
                std::cerr  << "Invalid segmentation method." << std::endl;
@@ -218,9 +216,5 @@ int main(int argc, char *argv[])
 out_delete_trail:
        delete trail;
 out:
-       delete drawing_method;
-       delete segmentation_method;
-       delete output_file;
-       delete input_file;
        return ret;
 }