⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.cpp

📁 MySQL数据库开发源码 值得一看哦
💻 CPP
字号:
// memory.cpp#include "../../include/lock.hpp"     // locking#include <new>          // std::bad_alloc#include <cstdlib>      // malloc#include <cstring>      // memset#include <fstream>      // ofstream#include <sstream>      // stringstream#include <cassert>      // assert#include <iomanip>      // setiosflags/*********************************************************************To use MemoryTracker merely add this file to your projectNo need to instantiate anythingIf your app is multi threaded define MULTI_THREADED*********************************************************************/// localsnamespace {class MemoryTracker {    std::ofstream log_;public:    MemoryTracker();    ~MemoryTracker();private:    MemoryTracker(const MemoryTracker&);             // hide copy    MemoryTracker& operator=(const MemoryTracker&);  // and assign    void LogStats();};struct alloc_node {    alloc_node* left_;    alloc_node* right_;      alloc_node() : left_(0), right_(0) {}};alloc_node* Root = 0;size_t Allocs    = 0;size_t DeAllocs  = 0;size_t Bytes     = 0;struct size_tracker {    size_t size_;    size_t count_;};size_tracker sizes[] = {    {0,0},    {2,0},    {4,0},    {8,0},    {16,0},    {32,0},    {64,0},    {128,0},    {256,0},    {512,0},    {1024,0},    {2048,0},    {4096,0},    {8192,0},};const size_t size_elements(sizeof(sizes) / sizeof(size_tracker));bool Tracking(false);using   yaSSL::Mutex;typedef Mutex::Lock Lock;Mutex mutex;MemoryTracker theTracker;bool lookup(alloc_node*& find, void* key, alloc_node*& prev){    bool found(false);    while (find) {        if (find == key) {            found = true;            break;        }        prev = find;        if (key < find)            find = find->left_;        else            find = find->right_;    }    return found;}// iterative insertvoid insert(alloc_node* entry){    if (!Root) {        Root = entry;        return;    }           alloc_node* tmp  = Root;    alloc_node* prev = 0;    if (lookup(tmp, entry, prev))         assert(0); // duplicate    if (entry < prev)        prev->left_  = entry;    else        prev->right_ = entry;}alloc_node* predecessorSwap(alloc_node* del){    alloc_node* pred = del->left_;    alloc_node* predPrev = del;    while (pred->right_) {        predPrev = pred;        pred = pred->right_;    }    if (predPrev == del)        predPrev->left_  = pred->left_;    else        predPrev->right_ = pred->left_;    pred->left_  = del->left_;    pred->right_ = del->right_;    return pred;}// iterative removevoid remove(void* ptr){    alloc_node* del  = Root;    alloc_node* prev = 0;    alloc_node* replace = 0;    if ( lookup(del, ptr, prev) == false)        assert(0); // oops, not there    if (del->left_ && del->right_)          // two children        replace = predecessorSwap(del);    else if (!del->left_ && !del->right_)   // no children        replace = 0;    else                                    // one child        replace = (del->left_) ? del->left_ : del->right_;    if (del == Root)        Root = replace;    else if (prev->left_ == del)        prev->left_  = replace;    else        prev->right_ = replace;}typedef void (*fp)(alloc_node*, void*);void applyInOrder(alloc_node* root, fp f, void* arg){    if (root == 0)        return;        applyInOrder(root->left_,  f, arg);    f(root, arg);    applyInOrder(root->right_, f, arg);}void show(alloc_node* ptr, void* arg){    std::ofstream* log = static_cast<std::ofstream*>(arg);    *log << ptr << '\n';}MemoryTracker::MemoryTracker() : log_("memory.log"){#ifdef __GNUC__    // Force pool allocator to cleanup at exit    setenv("GLIBCPP_FORCE_NEW", "1", 0);#endif#ifdef _MSC_VER    // msvc6 needs to create Facility for ostream before main starts, otherwise    // if another ostream is created and destroyed in main scope, log stats    // will access a dead Facility reference (std::numput)    int msvcFac = 6;    log_ << "MSVC " << msvcFac << "workaround" << std::endl; #endif    Tracking = true;}MemoryTracker::~MemoryTracker(){    // stop tracking before log (which will alloc on output)    Tracking = false;    LogStats();    //assert(Allocs == DeAllocs);    //assert(Root == 0);}void MemoryTracker::LogStats(){    log_ << "Number of Allocs:     " << Allocs    << '\n';    log_ << "Number of DeAllocs:   " << DeAllocs  << '\n';    log_ << "Number of bytes used: " << Bytes     << '\n';    log_ << "Alloc size table:\n";    log_ << " Bytes " << '\t' << "   Times\n";    for (size_t i = 0; i < size_elements; ++i) {        log_ << " " << sizes[i].size_  << "  " << '\t';        log_ << std::setiosflags(std::ios::right) << std::setw(8);        log_ << sizes[i].count_ << '\n';    }    if (Allocs != DeAllocs) {        log_<< "Showing new'd allocs with no deletes" << '\n';        applyInOrder(Root, show, &log_);    }    log_.flush();}// return power of 2 up to size_tracker elementssize_t powerOf2(size_t sz){    size_t shifts = 0;    if (sz)        sz -= 1;    else        return 0;	       while (sz) {        sz >>= 1;        ++shifts;    }    return shifts < size_elements ? shifts : size_elements;}} // namespace localvoid* operator new(size_t sz){    // put alloc node in front of requested memory    void* ptr = malloc(sz + sizeof(alloc_node));    if (ptr) {        if (Tracking) {            Lock l(mutex);            ++Allocs;            Bytes += sz;            ++sizes[powerOf2(sz)].count_;            insert(new (ptr) alloc_node);        }        return static_cast<char*>(ptr) + sizeof(alloc_node);    }    else        assert(0);}void operator delete(void* ptr){    if (ptr) {        ptr = static_cast<char*>(ptr) - sizeof(alloc_node);  // correct offset        if (Tracking) {            Lock l(mutex);            ++DeAllocs;            remove(ptr);        }        free(ptr);    }}void* operator new[](size_t sz){    return ::operator new(sz);}void operator delete[](void* ptr){    ::operator delete(ptr);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -