कल की समाधान के लिए इस्तेमाल किया उत्पादन विश्लेषण करने के लिए पर्ल जाहिर है, एक सी ++ जनसंपर्क किया जा रहा है ogrammer मुझे इसे C++ में करना है। मैंने पहले std::regex
का उपयोग नहीं किया था और इस बारे में कुछ सीखने की आवश्यकता है। तो यहाँ एक सी ++ समाधान है:
#include "boost/regex.hpp"
#include <functional>
#include <iostream>
#include <iterator>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>
namespace re = boost;
long to_long(std::string const& s)
{
return strtol(s.c_str(), 0, 10);
}
template <typename T>
static void insert(T& map, std::string const& address, std::string const& call, size_t size)
{
if (!map.insert(std::make_pair(address, std::make_pair(call, size))).second)
std::cout << "WARNING: duplicate address for " << call << ": " << address << "\n";
}
template <typename T>
static void erase(T& map, std::string const& address, std::string const& call)
{
auto it(map.find(address));
if (it == map.end() && address != "0x0")
std::cout << "WARNING: spurious address in " << call << "\n";
else
map.erase(it);
}
static void process(std::istream& in)
{
std::map<std::string, std::pair<std::string, size_t>> m;
std::vector<std::pair<re::regex, std::function<void(re::smatch&)>>> exps;
exps.emplace_back(re::regex(".*(malloc\\((.*)\\)) = (.*)"), [&](re::smatch& results){
::insert(m, results[3], results[1], ::to_long(results[2]));
});
exps.emplace_back(re::regex(".*(free\\((.*)\\))"), [&](re::smatch& results){
::erase(m, results[2], results[1]);
});
exps.emplace_back(re::regex(".*(calloc\\((.*),(.*)\\)) = (.*)"), [&](re::smatch& results){
::insert(m, results[4], results[1], ::to_long(results[2]) * ::to_long(results[3]));
});
exps.emplace_back(re::regex(".*(realloc\\((.*),(.*)\\)) = (.*)"), [&](re::smatch& results){
::erase(m, results[2], results[1]);
::insert(m, results[4], results[1], ::to_long(results[3]));
});
for (std::string line; std::getline(in, line);)
{
re::smatch results;
for (auto it(exps.begin()), end(exps.end()); it != end; ++it)
{
if (re::regex_match(line, results, it->first))
{
(it->second)(results);
break;
}
}
}
size_t total{0};
for (auto it(m.begin()), end(m.end()); it != end; ++it)
{
std::cout << "leaked memory at " << it->first << " " << "from " << it->second.first << "\n";
total += it->second.second;
}
std::cout << "total leak: " << total << "\n";
}
int main(int, char*[])
{
try
{
::process(std::cin);
}
catch (std::exception const &ex)
{
std::cerr << "ERROR: " << ex.what() << "\n";
}
}
क्योंकि ऐसा लगता है कि जीसीसी के std::regex
के वर्तमान संस्करण गाड़ी है मैं बूस्ट से कार्यान्वयन का इस्तेमाल किया। संस्करण को स्विच करना आसान होना चाहिए: boost
के बजाय std
के लिए उपनाम होने के लिए बस re
को उपनाम दें।
हां, आउटपुट संभावित लाइनों का प्रदर्शन करने के लिए सिर्फ एक उदाहरण है! मुझे स्क्रिप्ट का प्रयास करने दो - धन्यवाद! ओह, क्या आप इसे उन सभी लाइनों को अनदेखा कर सकते हैं जो पैटर्न में फिट नहीं हैं? –
बहुत अच्छा। एक सवाल: क्या यह 'realloc' की विभिन्न संभावनाओं के लिए खाता है? यह या तो एक सीधा नया 'मॉलोक' हो सकता है, या यह एक मौजूदा पते को चारों ओर स्थानांतरित कर सकता है। (इसके अलावा, 'मुक्त (0) 'नकली नहीं है :-)।) –
एक कीट होने के लिए खेद है: क्या आप इसे अंतिम लीक राशि जोड़ सकते हैं? मैं इसे Valgrind की अपनी रिपोर्ट से तुलना करना चाहता हूं। वास्तव में –