Dünün çözümü kullanılan perl, C++ pr olmak:. (her ne kadar muhtemelen oldukça hantal) perl komut standart girdiden Valgrind çıkışını okurken basit ogrammer C++ 'da yapmam gerekiyor. Daha önce std::regex
kullanmamıştım ve önce bunun hakkında biraz bilgi edinmem gerekiyordu. o std::regex
ait gcc en güncel sürümü aracı işte ben Boost gelen uygulanmasını kullanılan görünüyor Çünkü
#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";
}
}
: Yani burada bir C++ çözümdür. Versiyonu değiştirmek kolay olmalı: 'u boost
yerine std
için bir takma ad olarak tanımlayın.
Evet, çıktı olası satırları göstermek için bir örnektir! Senaryoyu deneyeyim - teşekkürler! Oh, kalıba uymayan tüm satırları görmezden gelebilir misin? –
Çok hoş. Bir soru: Bu, 'realloc'un çeşitli olasılıkları için mi hesap yapıyor? Düz bir yeni 'malloc' olabilir veya mevcut bir adresi etrafa taşıyabilir. (Ayrıca, özgür (0) 'sahte değil :-).) –
Zararlı olduğum için üzgünüm: Sızdıran son miktarı ekleyebilir misin? Valgrind'in kendi raporuyla karşılaştırmak istiyorum. –