From 21adbf9205a5c28a036ddd2373d85a9662e9b7fc Mon Sep 17 00:00:00 2001
From: Antonio Ospite <ao2@ao2.it>
Date: Sat, 10 Oct 2020 19:38:10 +0200
Subject: [PATCH] opencv_trail_effect.cpp: fix potential leak when exiting
 during option parsing

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 | 38 ++++++++++++++++----------------------
 1 file changed, 16 insertions(+), 22 deletions(-)

diff --git a/opencv_trail_effect.cpp b/opencv_trail_effect.cpp
index 357cc42..bc5b187 100644
--- a/opencv_trail_effect.cpp
+++ b/opencv_trail_effect.cpp
@@ -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;
 }
-- 
2.1.4