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

📄 memcheck.cpp

📁 Think in C++ 第二版源码
💻 CPP
字号:
//: C26:MemCheck.cpp {O}

// From Thinking in C++, 2nd Edition

// Available at http://www.BruceEckel.com

// (c) Bruce Eckel 1999

// Copyright notice in Copyright.txt

// Memory allocation tester

#include <cstdlib>

#include <cstring>

#include <cstdio>

using namespace std;

// MemCheck.h must not be included here



// Output file object using cstdio

// (cout constructor calls malloc())

class OFile {

  FILE* f;

public:

  OFile(char* name) : f(fopen(name, "w")) {}

  ~OFile() { fclose(f); }

  operator FILE*() { return f; }

};

extern OFile memtrace;

// Comment out the following to send all the

// information to the trace file:

#define memtrace stdout



const unsigned long _pool_sz = 50000L;

static unsigned char _memory_pool[_pool_sz];

static unsigned char* _pool_ptr = _memory_pool;



void* getmem(size_t sz) {

  if(_memory_pool + _pool_sz - _pool_ptr < sz) {

    fprintf(stderr,

           "Out of memory. Use bigger model\n");

    exit(1);

  }

  void* p = _pool_ptr;

  _pool_ptr += sz;

  return p;

}



// Holds information about allocated pointers:

class MemBag { 

public:

  enum type { Malloc, New };

private:

  char* typestr(type t) {

    switch(t) {

      case Malloc: return "malloc";

      case New: return "new";

      default: return "?unknown?";

    }

  }

  struct M {

    void* mp;  // Memory pointer

    type t;     // Allocation type

    char* file; // File name where allocated

    int line;  // Line number where allocated

    M(void* v, type tt, char* f, int l)

      : mp(v), t(tt), file(f), line(l) {}

  }* v;

  int sz, next;

  static const int increment = 50 ;

public:

  MemBag() : v(0), sz(0), next(0) {}

  void* add(void* p, type tt = Malloc,

            char* s = "library", int l = 0) {

    if(next >= sz) {

      sz += increment;

      // This memory is never freed, so it

      // doesn't "get involved" in the test:

      const int memsize = sz * sizeof(M);

      // Equivalent of realloc, no registration:

      void* p = getmem(memsize);

      if(v) memmove(p, v, memsize);

      v = (M*)p;

      memset(&v[next], 0,

             increment * sizeof(M));

    }

    v[next++] = M(p, tt, s, l);

    return p;

  }

  // Print information about allocation:

  void allocation(int i) {

    fprintf(memtrace, "pointer %p"

      " allocated with %s",

      v[i].mp, typestr(v[i].t));

    if(v[i].t == New)

      fprintf(memtrace, " at %s: %d",

        v[i].file, v[i].line);

    fprintf(memtrace, "\n");

  }

  void validate(void* p, type T = Malloc) {

    for(int i = 0; i < next; i++)

      if(v[i].mp == p) {

        if(v[i].t != T) {

          allocation(i);

          fprintf(memtrace,

          "\t was released as if it were "

          "allocated with %s \n", typestr(T));

        }

        v[i].mp = 0;  // Erase it

        return;

      }

    fprintf(memtrace,

    "pointer not in memory list: %p\n", p);

  }

  ~MemBag() {

    for(int i = 0; i < next; i++)

      if(v[i].mp != 0) {

        fprintf(memtrace,

        "pointer not released: ");

        allocation(i);

      }

  }

};

extern MemBag MEMBAG_;



void* malloc(size_t sz) {

  void* p = getmem(sz);

  return MEMBAG_.add(p, MemBag::Malloc);

}



void* calloc(size_t num_elems, size_t elem_sz) {

  void* p = getmem(num_elems * elem_sz);

  memset(p, 0, num_elems * elem_sz);

  return MEMBAG_.add(p, MemBag::Malloc);

}  



void* realloc(void* block, size_t sz) {

  void* p = getmem(sz);

  if(block) memmove(p, block, sz);

  return MEMBAG_.add(p, MemBag::Malloc);

}



void free(void* v) { 

  MEMBAG_.validate(v, MemBag::Malloc);

}



void* operator new(size_t sz) {

  void* p = getmem(sz);

  return MEMBAG_.add(p, MemBag::New);

}



void*

operator new(size_t sz, char* file, int line) {

  void* p = getmem(sz);

  return MEMBAG_.add(p, MemBag::New, file,line);

}



void operator delete(void* v) {

  MEMBAG_.validate(v, MemBag::New);

}



MemBag MEMBAG_;

// Placed here so the constructor is called

// AFTER that of MEMBAG_ :

#ifdef memtrace

#undef memtrace

#endif

OFile memtrace("memtrace.out");

// Causes 1 "pointer not in memory list" message

///:~

⌨️ 快捷键说明

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