From: Gurusamy Sarathy Date: Mon, 9 Jun 2003 14:09:55 +0000 (+0000) Subject: windows: fix memory leak in %ENV handling (shows up as a X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=2b93cd4d46ec719fcb7815a283251a218f198212;p=p5sagit%2Fp5-mst-13.2.git windows: fix memory leak in %ENV handling (shows up as a leak even in the simplest fork() loop, because perl_construct() now does the equivalent of %ENV assignments using mg_set()) p4raw-id: //depot/perl@19717 --- diff --git a/win32/perlhost.h b/win32/perlhost.h index 371a3a5..3b6d11d 100644 --- a/win32/perlhost.h +++ b/win32/perlhost.h @@ -2057,7 +2057,7 @@ CPerlHost::CPerlHost(CPerlHost& host) CPerlHost::~CPerlHost(void) { -// Reset(); + Reset(); InterlockedDecrement(&num_hosts); delete m_pvDir; m_pVMemParse->Release(); @@ -2118,6 +2118,8 @@ lookup(const void *arg1, const void *arg2) LPSTR* CPerlHost::Lookup(LPCSTR lpStr) { + if (!lpStr) + return NULL; return (LPSTR*)bsearch(&lpStr, m_lppEnvList, m_dwEnvCount, sizeof(LPSTR), lookup); } @@ -2169,20 +2171,24 @@ CPerlHost::Add(LPCSTR lpStr) // replacing ? lpPtr = Lookup(szBuffer); - if(lpPtr != NULL) { - Renew(*lpPtr, length, char); + if (lpPtr != NULL) { + // must allocate things via host memory allocation functions + // rather than perl's Renew() et al, as the perl interpreter + // may either not be initialized enough when we allocate these, + // or may already be dead when we go to free these + *lpPtr = (char*)Realloc(*lpPtr, length * sizeof(char)); strcpy(*lpPtr, lpStr); } else { - ++m_dwEnvCount; - Renew(m_lppEnvList, m_dwEnvCount, LPSTR); - New(1, m_lppEnvList[m_dwEnvCount-1], length, char); - if(m_lppEnvList[m_dwEnvCount-1] != NULL) { - strcpy(m_lppEnvList[m_dwEnvCount-1], lpStr); - qsort(m_lppEnvList, m_dwEnvCount, sizeof(LPSTR), compare); + m_lppEnvList = (LPSTR*)Realloc(m_lppEnvList, (m_dwEnvCount+1) * sizeof(LPSTR)); + if (m_lppEnvList) { + m_lppEnvList[m_dwEnvCount] = (char*)Malloc(length * sizeof(char)); + if (m_lppEnvList[m_dwEnvCount] != NULL) { + strcpy(m_lppEnvList[m_dwEnvCount], lpStr); + ++m_dwEnvCount; + qsort(m_lppEnvList, m_dwEnvCount, sizeof(LPSTR), compare); + } } - else - --m_dwEnvCount; } } @@ -2325,11 +2331,13 @@ CPerlHost::Reset(void) dTHX; if(m_lppEnvList != NULL) { for(DWORD index = 0; index < m_dwEnvCount; ++index) { - Safefree(m_lppEnvList[index]); + Free(m_lppEnvList[index]); m_lppEnvList[index] = NULL; } } m_dwEnvCount = 0; + Free(m_lppEnvList); + m_lppEnvList = NULL; } void