Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Access violation reading location 0x0000000000000004

Ostatnio zmodyfikowano 2015-12-30 18:34
Autor Wiadomość
TheReclif
Temat założony przez niniejszego użytkownika
[C++] Access violation reading location 0x0000000000000004
» 2015-12-29 18:21:28
Witam,
Pisałem ostatnio, w ramach eksperymentu, statyczną bibliotekę dla aplikacji okienkowych. Uznałem, że dobrze by było, gdyby dokumentowała swoje działanie w formie pisania logu, dlatego stworzyłem odpowiednią klasę.
Pliki występujące w bibliotece to: Log.h, Log.cpp, Error.h i Error.cpp. Potem powiem, dlaczego nie ma tu plików z klasami dla okien. Treść:

Log.h:
C/C++
class LogMgr
{
private:
    wofstream file;
    wstring filename;
    wstring endMessage;
   
    void writeTimeAsyncLine( _In_ const wstring lineToWrite );
public:
    LogMgr( void );
    LogMgr( _In_ const wstring nameOfFile, _In_opt_ const bool openOnCreate = false, _In_opt_ const wstring message = L"End of app work.\nEnd of autogenerated log file" );
    ~LogMgr( void );
   
    const wstring getFilename( void ) const;
    const wstring getEndMessage( void ) const;
   
    bool openFile( void );
   
    void writeLine( _In_ const wstring lineToWrite );
    void closeFile( void );
    void setEndMsg( _In_ wstring message );
   
    void operator <<( _In_ const wstring text );
    void operator =( _In_ const LogMgr & arg );
};

static LogMgr stdLogMgr( L"log.log", true );

Log.cpp:
C/C++
#include "Log.h"

void LogMgr::writeTimeAsyncLine( _In_ const wstring lineToWrite )
{
    wstring temp = lineToWrite + L"\n";
   
    file << temp.c_str();
}

LogMgr::LogMgr( void )
{
    filename = L"log.log";
}

LogMgr::LogMgr( _In_ const wstring nameOfFile, _In_opt_ const bool openOnCreate, _In_opt_ const wstring message )
{
    filename = nameOfFile;
    endMessage = message;
    if( openOnCreate )
         openFile();
   
}

LogMgr::~LogMgr( void )
{
    writeLine( endMessage );
    closeFile();
}

const wstring LogMgr::getFilename( void ) const
{
    return filename;
}

const wstring LogMgr::getEndMessage( void ) const
{
    return endMessage;
}

bool LogMgr::openFile( void )
{
    file.open( filename, ios::out | ios::trunc );
    if( file.bad() )
    {
        throw L"GlowE LogMgr error: can't open file";
        return false;
    }
    else
    {
        writeTimeAsyncLine( L"-----------------------Autogenerated log-------------------------" );
        writeLine( L"LogMgr created." );
        return true;
    }
}

void LogMgr::writeLine( _In_ const wstring lineToWrite )
{
    time_t currentTime = time( NULL );
    tm * timeStruct = new tm;
   
    localtime_s( timeStruct, & currentTime );
   
    wchar_t date[ 240 ];
    wcsftime( date, 240, L"%c: ", timeStruct );
   
    delete timeStruct;
   
    wstring temp = date + lineToWrite + L"\n";
   
    file << temp.c_str();
}

void LogMgr::closeFile( void )
{
    if( file.is_open() ) file.close();
   
}

void LogMgr::setEndMsg( _In_ wstring message )
{
    endMessage = message;
}

void LogMgr::operator <<( _In_ const wstring text )
{
    writeLine( text );
}

void LogMgr::operator =( _In_ const LogMgr & arg )
{
    filename = arg.getFilename();
    endMessage = arg.getEndMessage();
}

Error.h:
C/C++
enum ERROR_MGR_INPUT_TYPE
{
    NOTHING = 0,
    WARNING,
    TOTAL_FAILURE
};

class ErrorInfo
{
private:
    wstring place;
    wstring desc;
    ERROR_MGR_INPUT_TYPE type;
public:
    ErrorInfo( _In_ wstring descArg, _In_ wstring placeArg, _In_ ERROR_MGR_INPUT_TYPE typeArg );
    ~ErrorInfo( void ) { }
   
    wstring getErrorPlace( void );
    wstring getErroDesc( void );
    wstring getErrorTypeAsWstring( void );
   
    ERROR_MGR_INPUT_TYPE getErrorType( void );
};

class ErrorMgr
{
    ERROR_MGR_INPUT_TYPE message;
    LogMgr stdErrorLogMgr;
    wstring failureDesc;
    wstring failurePlace;
    bool isFailure;
   
    void writeErrorDesc( void );
public:
    ErrorMgr( void );
    ~ErrorMgr( void );
   
    void throwError( _In_ const wstring desc, _In_ const wstring place, _In_opt_ const ERROR_MGR_INPUT_TYPE failureType = TOTAL_FAILURE );
   
    ERROR_MGR_INPUT_TYPE getMessage( void );
   
    bool checkIsFailure( void );
};

static ErrorMgr stdErrorMgr;

Error.cpp:
C/C++
#include "Error.h"

void ErrorMgr::writeErrorDesc( void )
{
    stdErrorLogMgr.openFile();
    switch( message )
    {
    case WARNING:
        stdLogMgr << L"WARNING! WARNING! WARNING! WARNING!";
        stdLogMgr << L"The application has thrown a warning!";
        stdLogMgr << L"Check crashlog.log";
       
        stdErrorLogMgr << L"WARNING!";
        stdErrorLogMgr << failureDesc;
        stdErrorLogMgr << failurePlace;
        break;
    case TOTAL_FAILURE:
        isFailure = true;
        stdLogMgr << L"ATTENTION! TOTAL APPLICATION FAILURE! ATTENTION!";
        stdLogMgr << L"Shuting down in progress...";
        stdLogMgr << L"Check crashlog.log";
       
        stdErrorLogMgr << L"CRASH! TOTAL APPLICATION FAILURE! CRASH!";
        stdErrorLogMgr << failureDesc;
        stdErrorLogMgr << failurePlace;
        stdErrorLogMgr << L"CRASH! TOTAL APPLICATION FAILURE! CRASH!";
        break;
    default:
        stdLogMgr << L"Fake alarm.";
       
        stdErrorLogMgr << L"Fake alarm.";
        break;
    }
}

ErrorMgr::ErrorMgr( void )
{
    stdErrorLogMgr = LogMgr( L"crashlog.log", false );
    stdErrorLogMgr.setEndMsg( L"End of crashlog.\nEND OF CRASHLOG" );
    stdLogMgr << L"Error menager created.";
}

ErrorMgr::~ErrorMgr( void )
{
}

void ErrorMgr::throwError( _In_ const wstring desc, _In_ const wstring place, _In_opt_ const ERROR_MGR_INPUT_TYPE failureType )
{
    message = failureType;
    failureDesc = desc;
    failurePlace = place;
    writeErrorDesc();
    throw ErrorInfo( failureDesc, failurePlace, message );
}

ERROR_MGR_INPUT_TYPE GLOWE::ErrorMgr::getMessage( void )
{
    return message;
}

bool ErrorMgr::checkIsFailure( void )
{
    return isFailure;
}

ErrorInfo::ErrorInfo( _In_ wstring descArg, _In_ wstring placeArg, _In_ ERROR_MGR_INPUT_TYPE typeArg )
{
    place = placeArg;
    desc = descArg;
    type = typeArg;
}

wstring ErrorInfo::getErrorPlace( void )
{
    return place;
}

wstring ErrorInfo::getErroDesc( void )
{
    return desc;
}

wstring ErrorInfo::getErrorTypeAsWstring( void )
{
    switch( type )
    {
    case ERROR_MGR_INPUT_TYPE::NOTHING:
        return L"NOTHING";
        break;
    case ERROR_MGR_INPUT_TYPE::TOTAL_FAILURE:
        return L"TOTAL_FAILURE";
        break;
    case ERROR_MGR_INPUT_TYPE::WARNING:
        return L"WARNING";
        break;
    }
}

ERROR_MGR_INPUT_TYPE ErrorInfo::getErrorType( void )
{
    return type;
}

Przejdę teraz do sedna: żeby przetestować nowopowstałą bibliotekę, napisałem prostego maina:
C/C++
#include <Windows.h>

#include "Error.h"

int WINAPI WinMain()
{
    try
    {
        //tu jakieś rzeczy z okienkami
        Sleep( 3000 );
    }
    catch( GLOWE::ErrorInfo info )
    {
        return info.getErrorType();
    }
    catch( wstring info )
    {
        return 0x051;
    }
   
    return 0;
}

Brak błędów linkowania ani kompilacji. Ale kiedy odpalam skompilowanego exeka to nic się
nie dzieje. Powinno stworzyć się okno, ale się nie tworzy. Kiedy odpaliłem
debuggera okazało się, że mam błąd odczytywania pamięci, a IDE przekierowało mnie... na 873 linijkę
pliku ostream.h (pokaże ją tutaj):
C/C++
streamsize _Pad = _Ostr.width() <= 0 || _Ostr.width() <= _Count
? 0
    : _Ostr.width() - _Count;
Wartość _Pad w tym momencie to -3689348814741910324.
Czemu błąd jest akurat tutaj? I czy może być to spowodowane użyciem statycznej zmiennej zadeklarowanej w statycznej bibliotece?
P-142552
j23
» 2015-12-29 20:16:42
W debugerze masz okno callstack. Użyj go, będziesz wiedział, w którym miejscu twojego kodu wystrzeliło.

Jeśli chodzi o te zmienne static w nagłówkach, lepiej zrób tak:
C/C++
class LogMgr
{
public:
    ...
   
   
    static LogMgr & get()
    {
        static LogMgr stdLogMgr( L"log.log", true );
        return stdLogMgr;
    }
};



// użycie
LogMgr::get() << L"ATTENTION! TOTAL APPLICATION FAILURE! ATTENTION!";
LogMgr::get() << L"Shuting down in progress...";
LogMgr::get() << L"Check crashlog.log";
P-142562
TheReclif
Temat założony przez niniejszego użytkownika
» 2015-12-30 18:34:57
Dzięki za odpowiedź, naprawione :). Temat zamykam.
P-142600
« 1 »
  Strona 1 z 1