windows: fix memory leak in %ENV handling (shows up as a
Gurusamy Sarathy [Mon, 9 Jun 2003 14:09:55 +0000 (14:09 +0000)]
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

win32/perlhost.h

index 371a3a5..3b6d11d 100644 (file)
@@ -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