I wrote the following C++ code based on the Boost library to take inputs from command line.
#include <iostream>
#include <boost/program_options.hpp>
#include <boost/format.hpp>
using namespace std;
namespace po = boost::program_options;
int main(int argc, char** argv) {
int party = 2, port = 9999;
string server_ip;
po::options_description desc{"Allowed options"};
desc.add_options() //
("help,h", "produce help message") //
("party,k", po::value<int>(&party)->default_value(1), "party id: 1 for server, 2 for client") //
("port,p", po::value<int>(&port)->default_value(1234), "socket port") //
("server_ip,s", po::value<string>(&server_ip)->default_value("localhost"), "server's IP.");
po::variables_map vm;
try {
po::parsed_options parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run();
po::store(parsed, vm);
if (vm.count("help")) {
cout << desc << endl;
return 0;
}
po::notify(vm);
}catch (po::error& e) {
cout << "ERROR: " << e.what() << endl << endl;
cout << desc << endl;
return -1;
}
cout << party << endl;
cout << port << endl;
cout << server_ip << endl;
}
It works as intended. However, Klocwork reported the following error (I have adjusted the line numbers for this code snippet):
main.cpp:16 MLK.MUST (2:Error) Analyze
Memory leak. Dynamic memory stored in 'po::value<int> ( &party)' allocated through function 'value<int>' at line 14 is lost at line 16
* main.cpp:14: Dynamic memory stored in 'po::value<int> ( &party)' is allocated by calling function 'value<int>'.
* value_semantic.hpp:198: 'r' is allocated by function 'new'.
* main.cpp:16: Dynamic memory stored in 'po::value<int> ( &party)' is lost.
Current status 'Analyze'
I found this old post boost program_options generating a Klocwork MLK.MUST. However, after reading the answer, I still do not know how I can solve this issue.
Another issue reported by Klocwork is 'port' is used uninitialized in this function
. It specifically mentions that passing '&port' to 'po::value<int>' does not initialize 'port'
. However, after running the code, I see that it does initialize port since the value of port is printed as 1234 and not 9999.
Is there a way to write this code that will solve the above issues?
This is a false positive: nothing uses the value of
port
before it's initialized (I checked). However, it should be enough to actually initializingport
to silence the message, by. It's weird that it still triggers, since you already had that.Neither vaglrind nor ASAN+UBSAN find anything wrong with the code for me. Here's a brute force test that tries all kinds of option combinations (including unregistered and erroneous):
That ends up running 343 different invocations of the program and ends up printing the expected outputs:
The expected diagnostics:
And most importantly, consistent leak-free report:
TL;DR
I don't know why your tooling reports leaks. At the very least, the "'port' is used uninitialized" issue seems wrong on close inspection.
I tested on GCC 10 with Boost 1.73.0, -std=c++17 -O3, your source 1--% unaltered.
I hope this gives you more ideas and perhaps some reassurance.