昨天的溶液中使用的Perl分析輸出顯然,是一個C++ PR程序員我應該用C++來完成它。我之前沒有使用過std::regex
,需要先了解一下。因此,這裏是一個C++的解決方案:
#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
版本是越野車我使用加速實施。切換版本應該很容易:只需將re
定義爲std
的別名,而不是boost
。
是的,輸出只是一個示例來演示可能的行!讓我試試這個劇本 - 謝謝!哦,你能否讓它忽略所有不符合該模式的線? – 2012-01-06 00:14:35
非常好。一個問題:這是否說明了'realloc'的各種可能性?它可以是一個新的'malloc',也可以移動一個現有的地址。 (另外,'free(0)'不是虛假的:-)。) – 2012-01-06 00:37:18
對不起,您可以將最終的泄漏量加起來嗎?我想比較一下Valgrind自己的報告。 – 2012-01-06 00:39:22