memory.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,171 行 · 第 1/3 页
CPP
1,171 行
msg2.Printf(wxT(" at 0x%lX, size %d"), (long)GetActualData(), (int)RequestSize());
msg += msg2;
wxDebugContext::OutputDumpLine(msg);
}
else
{
wxString msg;
if (m_fileName)
msg.Printf(wxT("%s(%d): "), m_fileName, (int)m_lineNum);
wxString msg2;
msg2.Printf(wxT("non-object data at 0x%lX, size %d"), (long)GetActualData(), (int)RequestSize() );
msg += msg2;
wxDebugContext::OutputDumpLine(msg);
}
}
/*
Validate a node. Check to see that the node is "clean" in the sense
that nothing has over/underwritten it etc.
*/
int wxMemStruct::ValidateNode ()
{
char * startPointer = (char *) this;
if (!AssertIt ()) {
if (IsDeleted ())
ErrorMsg ("Object already deleted");
else {
// Can't use the error routines as we have no recognisable object.
#ifndef __WXGTK__
wxLogMessage(wxT("Can't verify memory struct - all bets are off!"));
#endif
}
return 0;
}
/*
int i;
for (i = 0; i < wxDebugContext::TotSize (requestSize ()); i++)
cout << startPointer [i];
cout << endl;
*/
if (Marker () != MemStartCheck)
ErrorMsg ();
if (* (wxMarkerType *) wxDebugContext::MidMarkerPos (startPointer) != MemMidCheck)
ErrorMsg ();
if (* (wxMarkerType *) wxDebugContext::EndMarkerPos (startPointer,
RequestSize ()) !=
MemEndCheck)
ErrorMsg ();
// Back to before the extra buffer and check that
// we can still read what we originally wrote.
if (Marker () != MemStartCheck ||
* (wxMarkerType *) wxDebugContext::MidMarkerPos (startPointer)
!= MemMidCheck ||
* (wxMarkerType *) wxDebugContext::EndMarkerPos (startPointer,
RequestSize ()) != MemEndCheck)
{
ErrorMsg ();
return 0;
}
return 1;
}
/*
The wxDebugContext class.
*/
wxMemStruct *wxDebugContext::m_head = NULL;
wxMemStruct *wxDebugContext::m_tail = NULL;
bool wxDebugContext::m_checkPrevious = false;
int wxDebugContext::debugLevel = 1;
bool wxDebugContext::debugOn = true;
wxMemStruct *wxDebugContext::checkPoint = NULL;
// For faster alignment calculation
static wxMarkerType markerCalc[2];
int wxDebugContext::m_balign = (int)((char *)&markerCalc[1] - (char*)&markerCalc[0]);
int wxDebugContext::m_balignmask = (int)((char *)&markerCalc[1] - (char*)&markerCalc[0]) - 1;
wxDebugContext::wxDebugContext(void)
{
}
wxDebugContext::~wxDebugContext(void)
{
}
/*
Work out the positions of the markers by creating an array of 2 markers
and comparing the addresses of the 2 elements. Use this number as the
alignment for markers.
*/
size_t wxDebugContext::CalcAlignment ()
{
wxMarkerType ar[2];
return (char *) &ar[1] - (char *) &ar[0];
}
char * wxDebugContext::StructPos (const char * buf)
{
return (char *) buf;
}
char * wxDebugContext::MidMarkerPos (const char * buf)
{
return StructPos (buf) + PaddedSize (sizeof (wxMemStruct));
}
char * wxDebugContext::CallerMemPos (const char * buf)
{
return MidMarkerPos (buf) + PaddedSize (sizeof(wxMarkerType));
}
char * wxDebugContext::EndMarkerPos (const char * buf, const size_t size)
{
return CallerMemPos (buf) + PaddedSize (size);
}
/*
Slightly different as this takes a pointer to the start of the caller
requested region and returns a pointer to the start of the buffer.
*/
char * wxDebugContext::StartPos (const char * caller)
{
return ((char *) (caller - wxDebugContext::PaddedSize (sizeof(wxMarkerType)) -
wxDebugContext::PaddedSize (sizeof (wxMemStruct))));
}
/*
We may need padding between various parts of the allocated memory.
Given a size of memory, this returns the amount of memory which should
be allocated in order to allow for alignment of the following object.
I don't know how portable this stuff is, but it seems to work for me at
the moment. It would be real nice if I knew more about this!
// Note: this function is now obsolete (along with CalcAlignment)
// because the calculations are done statically, for greater speed.
*/
size_t wxDebugContext::GetPadding (const size_t size)
{
size_t pad = size % CalcAlignment ();
return (pad) ? sizeof(wxMarkerType) - pad : 0;
}
size_t wxDebugContext::PaddedSize (const size_t size)
{
// Added by Terry Farnham <TJRT@pacbell.net> to replace
// slow GetPadding call.
int padb;
padb = size & m_balignmask;
if(padb)
return(size + m_balign - padb);
else
return(size);
}
/*
Returns the total amount of memory which we need to get from the system
in order to satisfy a caller request. This includes space for the struct
plus markers and the caller's memory as well.
*/
size_t wxDebugContext::TotSize (const size_t reqSize)
{
return (PaddedSize (sizeof (wxMemStruct)) + PaddedSize (reqSize) +
2 * sizeof(wxMarkerType));
}
/*
Traverse the list of nodes executing the given function on each node.
*/
void wxDebugContext::TraverseList (PmSFV func, wxMemStruct *from)
{
if (!from)
from = wxDebugContext::GetHead ();
wxMemStruct * st = NULL;
for (st = from; st != 0; st = st->m_next)
{
void* data = st->GetActualData();
// if ((data != (void*)m_debugStream) && (data != (void*) m_streamBuf))
if (data != (void*) wxLog::GetActiveTarget())
{
(st->*func) ();
}
}
}
/*
Print out the list.
*/
bool wxDebugContext::PrintList (void)
{
#ifdef __WXDEBUG__
TraverseList ((PmSFV)&wxMemStruct::PrintNode, (checkPoint ? checkPoint->m_next : (wxMemStruct*)NULL));
return true;
#else
return false;
#endif
}
bool wxDebugContext::Dump(void)
{
#ifdef __WXDEBUG__
{
wxChar* appName = (wxChar*) wxT("application");
wxString appNameStr;
if (wxTheApp)
{
appNameStr = wxTheApp->GetAppName();
appName = WXSTRINGCAST appNameStr;
OutputDumpLine(wxT("----- Memory dump of %s at %s -----"), appName, WXSTRINGCAST wxNow() );
}
else
{
OutputDumpLine( wxT("----- Memory dump -----") );
}
}
TraverseList ((PmSFV)&wxMemStruct::Dump, (checkPoint ? checkPoint->m_next : (wxMemStruct*)NULL));
OutputDumpLine(wxEmptyString);
OutputDumpLine(wxEmptyString);
return true;
#else
return false;
#endif
}
#ifdef __WXDEBUG__
struct wxDebugStatsStruct
{
long instanceCount;
long totalSize;
wxChar *instanceClass;
wxDebugStatsStruct *next;
};
static wxDebugStatsStruct *FindStatsStruct(wxDebugStatsStruct *st, wxChar *name)
{
while (st)
{
if (wxStrcmp(st->instanceClass, name) == 0)
return st;
st = st->next;
}
return NULL;
}
static wxDebugStatsStruct *InsertStatsStruct(wxDebugStatsStruct *head, wxDebugStatsStruct *st)
{
st->next = head;
return st;
}
#endif
bool wxDebugContext::PrintStatistics(bool detailed)
{
#ifdef __WXDEBUG__
{
wxChar* appName = (wxChar*) wxT("application");
wxString appNameStr;
if (wxTheApp)
{
appNameStr = wxTheApp->GetAppName();
appName = WXSTRINGCAST appNameStr;
OutputDumpLine(wxT("----- Memory statistics of %s at %s -----"), appName, WXSTRINGCAST wxNow() );
}
else
{
OutputDumpLine( wxT("----- Memory statistics -----") );
}
}
bool currentMode = GetDebugMode();
SetDebugMode(false);
long noNonObjectNodes = 0;
long noObjectNodes = 0;
long totalSize = 0;
wxDebugStatsStruct *list = NULL;
wxMemStruct *from = (checkPoint ? checkPoint->m_next : (wxMemStruct*)NULL );
if (!from)
from = wxDebugContext::GetHead ();
wxMemStruct *st;
for (st = from; st != 0; st = st->m_next)
{
void* data = st->GetActualData();
if (detailed && (data != (void*) wxLog::GetActiveTarget()))
{
wxChar *className = (wxChar*) wxT("nonobject");
if (st->m_isObject && st->GetActualData())
{
wxObject *obj = (wxObject *)st->GetActualData();
if (obj->GetClassInfo()->GetClassName())
className = (wxChar*)obj->GetClassInfo()->GetClassName();
}
wxDebugStatsStruct *stats = FindStatsStruct(list, className);
if (!stats)
{
stats = (wxDebugStatsStruct *)malloc(sizeof(wxDebugStatsStruct));
stats->instanceClass = className;
stats->instanceCount = 0;
stats->totalSize = 0;
list = InsertStatsStruct(list, stats);
}
stats->instanceCount ++;
stats->totalSize += st->RequestSize();
}
if (data != (void*) wxLog::GetActiveTarget())
{
totalSize += st->RequestSize();
if (st->m_isObject)
noObjectNodes ++;
else
noNonObjectNodes ++;
}
}
if (detailed)
{
while (list)
{
OutputDumpLine(wxT("%ld objects of class %s, total size %ld"),
list->instanceCount, list->instanceClass, list->totalSize);
wxDebugStatsStruct *old = list;
list = old->next;
free((char *)old);
}
OutputDumpLine(wxEmptyString);
}
SetDebugMode(currentMode);
OutputDumpLine(wxT("Number of object items: %ld"), noObjectNodes);
OutputDumpLine(wxT("Number of non-object items: %ld"), noNonObjectNodes);
OutputDumpLine(wxT("Total allocated size: %ld"), totalSize);
OutputDumpLine(wxEmptyString);
OutputDumpLine(wxEmptyString);
return true;
#else
(void)detailed;
return false;
#endif
}
bool wxDebugContext::PrintClasses(void)
{
{
wxChar* appName = (wxChar*) wxT("application");
wxString appNameStr;
if (wxTheApp)
{
appNameStr = wxTheApp->GetAppName();
appName = WXSTRINGCAST appNameStr;
wxLogMessage(wxT("----- Classes in %s -----"), appName);
}
}
int n = 0;
wxHashTable::compatibility_iterator node;
wxClassInfo *info;
wxClassInfo::sm_classTable->BeginFind();
node = wxClassInfo::sm_classTable->Next();
while (node)
{
info = (wxClassInfo *)node->GetData();
if (info->GetClassName())
{
wxString msg(info->GetClassName());
msg += wxT(" ");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?