Runtime check failure in CString destructor caused by setting Class ptr to NULL?

261 views Asked by At

so somewhere along the lines of putting this app together I've started to get a runtime check failure stack corruption when the destructor for a cstring class member is called. I've gotten to the point of trying to debug this by throwing bricks at the issue but still havent root caused it. At the current moment the class that the cstring resides in does nothing but initialize its private string members and set a pointer to another class to NULL.

Interestingly if I do not set the class pointer to NULL and comment out that line the corruption goes away. I think this is somewhat of a red herring, and that something is changing in the way the compiler is putting the code together when it pulls in the .h file that contains theCLog definitions and that would be used since I'm declaring a pointer to that object.

    int _tmain(int argc, _TCHAR* argv[])
{

    DWORD a = 0xBABA; //just to help catch the corrupter
    DWORD b = 0xDFDF;

    CStringW startat = L"\\\\anetworkshare\\fre";
    CStringW lookfor = L".inf";

    DirEnum myEnum(startat,lookfor);

    ULONG en = a + b;

    en = a - b;

    return 0;
}

DirEnum.cpp


DirEnum::DirEnum(CString startingdir,CString fileFilter)
{
    m_plogfile = NULL;  //If you comment out this line corruption goes away
    m_startingdir = L"";
    m_extfilter = L"";

    if(startingdir.GetLength() > 0)
        m_startingdir = startingdir;

    if(fileFilter.GetLength() > 0)
        m_extfilter = fileFilter;

    //following commented out to tshoot
    //CLogBase& ref = ref.GetInstance();
    //logBase = &ref;

    //m_plogfile = new CLog(L"DirEnumerator",L"logfile.txt",logINFO);

}

Now I suspect that something in the log.h file is causing a change to occuur in the ATL or CString libraries but I dont know what. Heres the log.h file

#pragma once

//#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // some CString constructors will be explicit

#ifndef UNICODE
#define UNICODE
#endif

#ifndef _UNICODE
#define _UNICODE
#endif


using namespace std;


#ifndef TYPEDEF_H
 #define TYPEDEF_H

#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <tchar.h>
#include <time.h>



    //simple defines to allow the TCHAR library to be used
    typedef std::basic_string<TCHAR> tstring;
    typedef std::basic_ostream<TCHAR> tostream;
    typedef std::basic_istream<TCHAR> tistream;
    typedef std::basic_ostringstream<TCHAR> tostringstream;
    typedef std::basic_istringstream<TCHAR> tistringstream;
    typedef std::basic_ofstream<TCHAR>   tofstream;




    #if defined(UNICODE) || defined(_UNICODE)
        #define tcout std::wcout
        #define tcin std::wcin
    #else
        #define tcout std::cout
        #define tcin std::cin;
    #endif


 #endif

#if defined DEBUG || defined (_DEBUG)
#define TOCONSOLE
#endif


typedef enum LOGLVL{logERROR =0,logWARN,logINFO,logDEBUG};

//CLogBase os a singleton log class. Intent is that you can establish a reference from anywhere in the project and write to the same file 
// without having locking issues or threading issues

class CLogBase
{
public:
    static CLogBase& GetInstance(CString logname = L"log.txt",LOGLVL lvl = logWARN);
    ~CLogBase(void);

    tostringstream& GetLog(LOGLVL level);
    tostringstream& GetStream(LOGLVL);

    void Forceflush();


private:
    CLogBase(CString file,LOGLVL lvl);

    //our outstream

    tostringstream m_os;

    tostringstream m_dummy;

    tofstream m_filestream;

    CString m_filename;
    LOGLVL m_reportlvl;


    //Private declarations to prevent copy constructors from being invoked; these are do nothig implimentations 
    CLogBase(CLogBase const&);              
    void operator=(CLogBase const&); 


};


class CLog
{
public:
    CLog(CString component);
    CLog(CString component,CString logname,LOGLVL lvl);
    ~CLog();
    void Log(LOGLVL,CString message);
    void CLog::Flush();

    tostringstream& CLog::GetStream(LOGLVL lvl);


private:
    CString m_componentname;
    CLogBase* m_logBase;
};
1

There are 1 answers

0
Himilou On

I thought I would answer this as I found the issue. this was not a coding problem per se but a visual studio issue. What happened was that I was storing the direnum.h file and .cpp file in a different directory than the one used for the main project. referencing the header with #include "..\somedir\direnum.h" at one point in time visual studio reported the file as locked and did I want to overwrite \ cancel etc. I choose overwrite but what seemed to happen was that this caused VS to COPY the files to the current project. All my troubleshooting attempts were being edited in the local somename.h file whtne opened in the editor but the compiler was doing the correct thing and pulling down the .h file from the location above.

removing switching to the now local copy of direnum.h and recompiling fixed this as it was compiling part of the code as ANSI and the other part as WCHAR