Strona startowa Ludzie pragną czasami się rozstawać, żeby móc tęsknić, czekać i cieszyć się z powrotem.Zgodnie z informacjami kapłanów, ‼bogowie" zamierzali ponownie przybyć z nieba wtedy, gdy gotowe już będą wielkie budowle wzniesione według zasad kalendarza...195 Murchison i Naydrad pomogły Conwayowi delikatnie wydostać ciało z szafki i zło- żyć je na stole diagnostycznym...juszu sprzymierzone miasta, wahające się próbował przeciągnąć na swoją stronę; wynik wojny dla obu stron nie był inny niż jej przy- gotowanie...– Jeśli to prawda, to dlaczego mi o tym opowiadasz? Zdradzasz tajemnice swego ojca...stosuje odrębny model społeczny wychowywania chłopców i dziewczynek(ojciec bawi się agresywniej z chłopcem niż dziewczynką, chłopcy dostająwiększe kary niż...Z jedzeniem tych zielsk najbardziej trzeba było pilnować się, żeby nie zobaczył Ott, bo ten cholernie za to bił...mi jedną uwagę...Barles doskonale wiedział: fakt, że serbski artylerzysta, na przykład, wystrzeli z moździe­rza nabój PPK-S1A, a nie PPK-SSB i trafi w kolejkę po chleb w... Jeszcze raz spróbujmy sobie wszystko przypomnieć...Bo pismo togo krolewica dziewicą porodzonegow trojakiem mieście Pisma nazywa królem luda żydowskiego:w jego dziwnem narodzeni;w jego uciesznem wielikich...
 

Ludzie pragną czasami się rozstawać, żeby móc tęsknić, czekać i cieszyć się z powrotem.

h
#ifndef MEMCHECK_H
#define MEMCHECK_H
#include <cstddef> // for size_t
 
// Hijack the new operator (both scalar and array versions)
void* operator new(std::size_t, const char*, long);
void* operator new[](std::size_t, const char*, long);
#define new new (__FILE__, __LINE__)
 
extern bool traceFlag;
#define TRACE_ON() traceFlag = true
#define TRACE_OFF() traceFlag = false
 
extern bool activeFlag;
#define MEM_ON() activeFlag = true
#define MEM_OFF() activeFlag = false
 
#endif
///:~
 
It is important that you include this file in any source file in which you want to track free store activity, but you must include it last (after your other #include directives). Most headers in the standard library are templates, and since most compilers use the inclusion model of template compilation (meaning all source code is in the headers), the macro that replaces new in MemCheck.h would usurp all instances of the new operator in the library source code (and would likely result in compile errors). Besides, you are only interested in tracking your own memory errors, not the library’s. Comment
In the following file, which contains the memory tracking implementation, everything is done with C standard I/O rather than with C++ iostreams. It shouldn’t make a difference, really, since we’re not interfering with iostreams’ use of the free store, but it’s safer to not take a chance. (Besides, we tried it, Some compilers complained, but all compilers were happy with the stdio version.) Comment
//: C02:MemCheck.cpp {O}
#include <cstdio>
#include <cstdlib>
#include <cassert>
using namespace std;
#undef new
 
// Global flags set by macros in MemCheck.h
bool traceFlag = true;
bool activeFlag = false;
 
namespace { // Anonymous namespace for added safety
 
// Memory map entry type
struct Info {
void* ptr;
const char* file;
long line;
};
 
// Memory map data
const size_t MAXPTRS = 10000u;
Info memMap[MAXPTRS];
size_t nptrs = 0;
 
// Searches the map for an address
bool findPtr(void* p) {
for (size_t i = 0; i < nptrs; ++i)
if (memMap[i].ptr == p)
return true;
return false;
}
 
void delPtr(void* p) {
int pos = findPtr(p);
assert(p >= 0);
// Remove pointer from map
for (int i = pos; i < nptrs-1; ++i)
memMap[i] = memMap[i+1];
--nptrs;
}
 
// Dummy type for static destructor
struct Sentinel {
~Sentinel() {
if (nptrs > 0) {
printf("Leaked memory at:\n");
for (size_t i = 0; i < nptrs; ++i)
printf("\t%p (file: %s, line %ld)\n",
memMap[i].ptr, memMap[i].file, memMap[i].line);
}
else
printf("No user memory leaks!\n");
}
};
 
// Static dummy object
Sentinel s;
 
} // End anonymous namespace
 
// Overload scalar new
void* operator new(size_t siz, const char* file,
long line) {
void* p = malloc(siz);
if (activeFlag) {
if (nptrs == MAXPTRS) {
printf("memory map too small (increase MAXPTRS)\n");
exit(1);
}
memMap[nptrs].ptr = p;
memMap[nptrs].file = file;
memMap[nptrs].line = line;
++nptrs;
}
if (traceFlag) {
printf("Allocated %u bytes at address %p ", siz, p);
printf("(file: %s, line: %ld)\n", file, line);
}
return p;
}
 
// Overload array new
void* operator new[](size_t siz, const char* file,
long line) {
return operator new(siz, file, line);
}
 
// Override scalar delete
void operator delete(void* p) {
if (findPtr(p) >= 0) {
free(p);
assert(nptrs > 0);
delPtr(p);
if (traceFlag)
printf("Deleted memory at address %p\n", p);
}
else if (!p && activeFlag)
printf("Attempt to delete unknown pointer: %p\n", p);
}
 
// Override array delete
void operator delete[](void* p) {
operator delete(p);
} ///:~
 
The Boolean flags traceFlag and activeFlag are global, so they can be modified in your code by the macros TRACE_ON( ), TRACE_OFF( ), MEM_ON( ), and MEM_OFF( ). In general, enclose all the code in your main( ) within a MEM_ON( )-MEM_OFF( ) pair so that memory is always tracked. Tracing, which echoes the activity of the replacement functions for operator new( ) and operator delete( ), is on by default, but you can turn it off with TRACE_OFF( ). In any case, the final results are always printed (see the test runs later in this chapter).
The MemCheck facility tracks memory by keeping all addresses allocated by operator new( ) in an array of Info structures, which also holds the file name and line number where the call to new occurred. As much information as possible is kept inside the anonymous namespace so as not to collide with any names you might have placed in the global namespace. The Sentinel class exists solely to have a static object’s destructor called as the program shuts down. This destructor inspects memMap to see if any pointers are waiting to be deleted (in which case you have a memory leak). Comment