游戏开发论坛

 找回密码
 立即注册
搜索
查看: 16866|回复: 3

关于0xC0000005: 读取位置 0x00000004 时发生访问冲突 的问题

[复制链接]

2

主题

40

帖子

43

积分

注册会员

Rank: 2

积分
43
发表于 2008-11-18 00:50:00 | 显示全部楼层 |阅读模式


#include "stdafx.h"
#include "database.h"


/*
        Implement CDatabase methods
*/
CDatabase::CDatabase()
{
        m_hEnv                = NULL;
}


CDatabase::~CDatabase()
{
}


bool CDatabase::Init()
{
        if ( SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_hEnv ) != SQL_SUCCESS )
           return false;

   if ( SQLSetEnvAttr( m_hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER ) != SQL_SUCCESS )
           return false;

   return true;
}


void CDatabase::Uninit()
{
        if ( m_hEnv )
        {
                SQLFreeHandle( SQL_HANDLE_ENV, m_hEnv );
                m_hEnv = NULL;
        }
}


void CDatabase::EnumDSN( void (*pfnEnum)( char *pSrcName, char *pSrcDesc ) )
{
        int nResult;
        int nDirection = SQL_FETCH_FIRST;

        char szName[DB_MAXBUF], szDesc[DB_MAXBUF];
        int  nNameLen, nDescLen;

        while ( true )
        {
                nResult = SQLDataSourcesA( m_hEnv,
                                                                  nDirection,
                                                                  (byte *) szName, DB_MAXBUF, (short *) &nNameLen,
                                                                  (byte *) szDesc, DB_MAXBUF, (short *) &nDescLen );

                if ( nResult == SQL_ERROR || nResult == SQL_NO_DATA )
                        break;

                pfnEnum( szName, szDesc );

                nDirection = SQL_FETCH_NEXT;
        }
}


CConnection * CDatabase::CreateConnection( char *pDSN, char *pID, char *pPassword )
{
        CConnection *pConn = new CConnection;
        if ( pConn == NULL )
                return NULL;

        if ( pConn->Init( m_hEnv, pDSN, pID, pPassword ) == false )
        {
                delete pConn;
                return NULL;
        }

        return pConn;
}


void CDatabase:estroyConnection( CConnection *pConn )
{
        pConn->Uninit();

        delete pConn;
}


/*
        Implement diagnostic record functions
*/
static void (*g_pfnRecord)( char *pState, int nErrCode, char *pDesc );


void CDatabase::SetDiagRec( void (*pfnRecord)( char *pState, int nErrCode, char *pDesc ) )
{
        g_pfnRecord = pfnRecord;
}


void CDatabase::UnsetDiagRec()
{
        g_pfnRecord = NULL;
}


void CDatabase::DiagRec( int nHandleType, SQLHANDLE hHandle )
{
        if ( g_pfnRecord == NULL )
                return;

        char szState[SQL_SQLSTATE_SIZE + 1];
        char szDesc[SQL_MAX_MESSAGE_LENGTH + 1];
        int  nDescLen;
        int  nNativeError;
        int  nResult;
        int  nRecCnt = 1;

        while ( true )
        {
                nResult = SQLGetDiagRecA( nHandleType,
                                                                 hHandle,
                                                                 nRecCnt++,
                                                                 (byte *) szState,
                                                                 (long *) &nNativeError,
                                                                 (byte *) szDesc,
                                                                 SQL_MAX_MESSAGE_LENGTH,
                                                                 (short *) &nDescLen );
               
                if ( nResult == SQL_NO_DATA || nResult == SQL_ERROR || nResult == SQL_INVALID_HANDLE )
                        break;

                g_pfnRecord( szState, nNativeError, szDesc );
        }
}


/*
        Implement CConnection methods
*/
CConnection::CConnection()
{
        m_hDBConn        = NULL;
}


CConnection::~CConnection()
{
}


bool CConnection::Init( SQLHENV hEnv, char *pDSN, char *pID, char *pPassword )
{
        int nResult;

        nResult = SQLAllocHandle( SQL_HANDLE_DBC, hEnv, &m_hDBConn );
        if ( nResult != SQL_SUCCESS )
        {
                CDatabase::DiagRec( SQL_HANDLE_ENV, hEnv );
                return false;
        }

        nResult = SQLConnectA( m_hDBConn,
                                                  (byte *) pDSN, SQL_NTS,
                                                  (byte *) pID, SQL_NTS,
                                                  (byte *) pPassword, SQL_NTS );
        if ( nResult != SQL_SUCCESS )
        {
                CDatabase::DiagRec( SQL_HANDLE_DBC, m_hDBConn );

                if ( nResult != SQL_SUCCESS_WITH_INFO )
                        return false;
        }

        return true;
}


void CConnection::Uninit()
{
        if ( m_hDBConn )   //提示这里出问题
        {
                SQLDisconnect( m_hDBConn );
                SQLFreeHandle( SQL_HANDLE_DBC, m_hDBConn );
                m_hDBConn = NULL;
        }
}


CRecordset * CConnection::CreateRecordset()
{
        CRecordset *pRec = new CRecordset;
        if ( pRec == NULL )
                return NULL;

        if ( pRec->Init( m_hDBConn ) == false )
        {
                delete pRec;
                return NULL;
        }

        return pRec;
}


void CConnection::DestroyRecordset( CRecordset *pRec )
{
        pRec->Uninit();
        delete pRec;
}


/*
        Implement CRecordset methods
*/
CRecordset::CRecordset()
{
        m_hStmt                = NULL;

        m_nRowCount        = 0;
        m_nCols                = 0;

        m_pColInfo        = NULL;
        m_pColData        = NULL;
}


CRecordset::~CRecordset()
{
}


bool CRecordset::Init( SQLHDBC hDBConn )
{
        if ( SQLAllocHandle( SQL_HANDLE_STMT, hDBConn, &m_hStmt ) != SQL_SUCCESS )
        {
                CDatabase::DiagRec( SQL_HANDLE_STMT, m_hStmt );
                return false;
        }

        return true;
}


void CRecordset::Uninit()
{
        if ( m_pColInfo )
        {
                delete[] m_pColInfo;
                m_pColInfo = NULL;
        }
       
        if ( m_pColData )
        {
                delete[] m_pColData;
                m_pColData = NULL;
        }

        if ( m_hStmt )
        {
                SQLFreeHandle( SQL_HANDLE_STMT, m_hStmt );
                m_hStmt = NULL;
        }
}


bool CRecordset::Execute( char *pQuery )
{
        int nResult;
        int nCount;

        nResult = SQLExecDirectA( m_hStmt, (byte *) pQuery, SQL_NTS );
        if ( nResult != SQL_SUCCESS )
        {
                CDatabase::DiagRec( SQL_HANDLE_STMT, m_hStmt );

                if ( nResult != SQL_SUCCESS_WITH_INFO )
                        return false;
        }

        m_nCols = 0;
        nResult = SQLNumResultCols( m_hStmt, (short *) &m_nCols );
        if ( nResult != SQL_SUCCESS && nResult != SQL_SUCCESS_WITH_INFO )
        {
                CDatabase::DiagRec( SQL_HANDLE_STMT, m_hStmt );
                return false;
        }
       
        // If cols is 0, the statement probably was a non-SELECT simply return.
        if ( m_nCols == 0 )
        {
                m_nRowCount = 0;
                SQLRowCount( m_hStmt, (long *) &m_nRowCount );
                return true;
        }

        m_pColInfo = new CColumnInfo[ m_nCols ];
        if ( m_pColInfo == NULL )
                return false;

        for ( nCount = 0; nCount < m_nCols; nCount++ )
        {
                nResult = SQLDescribeColA( m_hStmt,
                                                                  nCount + 1,
                                                                  (byte *) m_pColInfo[nCount].szColName, DB_MAXBUF,
                                                                  (short *) &m_pColInfo[nCount].nColNameSize,
                                                                  (short *) &m_pColInfo[nCount].nColType,
                                                                  (ULONG *) &m_pColInfo[nCount].nColSize,
                                                                  (short *) &m_pColInfo[nCount].nAllowDecimalDigit,
                                                                  (short *) &m_pColInfo[nCount].nAllowNull );       
               
                if ( nResult != SQL_SUCCESS )
                {
                        CDatabase::DiagRec( SQL_HANDLE_STMT, m_hStmt );

                        if ( nResult != SQL_SUCCESS_WITH_INFO )
                                return false;
                }
        }

        m_pColData = new CColumnData[ m_nCols ];
        if ( m_pColData == NULL )
                return false;

        for ( nCount = 0; nCount < m_nCols; nCount++ )
        {
                if ( m_pColData[nCount].AllocMemory( m_pColInfo[nCount].nColSize + 1 ) == false )
                        return false;

                nResult = SQLBindCol( m_hStmt,
                                                          nCount + 1,
                                                          SQL_C_CHAR,
                                                          m_pColData[nCount].pData,
                                                          m_pColInfo[nCount].nColSize + 1,
                                                          (long *) &m_pColData[nCount].nDataSize );

                if ( nResult != SQL_SUCCESS )
                {
                        CDatabase::DiagRec( SQL_HANDLE_STMT, m_hStmt );

                        if ( nResult != SQL_SUCCESS_WITH_INFO )
                                return false;
                }
        }

        return true;
}


bool CRecordset::Fetch()
{
        int nResult;

        nResult = SQLFetch( m_hStmt );
        if ( nResult != SQL_SUCCESS )
        {
                CDatabase::DiagRec( SQL_HANDLE_STMT, m_hStmt );

                if ( nResult != SQL_SUCCESS_WITH_INFO )
                        return false;
        }

        return true;
}


int CRecordset::GetRowCount()
{
        return m_nRowCount;
}


int CRecordset::GetCols()
{
        return m_nCols;
}


char * CRecordset::Get( char *pColName )
{
        for ( int nCount = 0; nCount < m_nCols; nCount++ )
        {
                if ( stricmp( m_pColInfo[nCount].szColName, pColName ) == 0 )
                        return m_pColData[nCount].pData;
        }

        return NULL;
}


char * CRecordset::Get( int nCol )
{
        if ( nCol < 0 || nCol >= m_nCols )
                return NULL;

        return m_pColData[ nCol ].pData;
}


CRecordset::CColumnInfo * CRecordset::GetColInfo( char *pColName )
{
        for ( int nCount = 0; nCount < m_nCols; nCount++ )
        {
                if ( stricmp( m_pColInfo[nCount].szColName, pColName ) == 0 )
                        return &m_pColInfo[nCount];
        }

        return NULL;
}


CRecordset::CColumnInfo * CRecordset::GetColInfo( int nCol )
{
        if ( nCol < 0 || nCol >= m_nCols )
                return NULL;
       
        return &m_pColInfo[nCol];
}


/*
        Implement CRecordset::CColumnInfo methods
*/
CRecordset::CColumnInfo::CColumnInfo()
{
        nColNameSize                = 0;
        szColName[0]                = '\0';
        nColType                        = 0;
        nColSize                        = 0;
        nAllowDecimalDigit        = 0;
        nAllowNull                        = 0;
}


CRecordset::CColumnInfo::~CColumnInfo()
{
}


/*
        Implement CRecordset::CColumnData methods
*/
CRecordset::CColumnData::CColumnData()
{
        pData                = NULL;
        nDataSize        = 0;
}


CRecordset::CColumnData::~CColumnData()
{
        if ( pData )
                delete[] pData;
}


bool CRecordset::CColumnData::AllocMemory( int nSize )
{
        pData = new char[ nSize ];
        if ( pData == NULL )
                return false;

        memset( pData, 0, nSize );

        return true;
}


报错误
DBSvr.exe 中的 0x004529f6 处最可能的异常: 0xC0000005: 读取位置 0x00000004 时发生访问冲突
DBSvr.exe 中的 0x004529f6 处未处理的异常: 0xC0000005: 读取位置 0x00000004 时发生访问冲突

要怎么解决,望哪位高手给小弟指点下,谢谢

1万

主题

1万

帖子

2万

积分

管理员

中级会员

Rank: 9Rank: 9Rank: 9

积分
20732
发表于 2008-11-18 10:23:00 | 显示全部楼层

Re:关于0xC0000005: 读取位置 0x00000004 时发生访问冲突 的问题

??最好你???版本跟?下就知道了。

3

主题

4

帖子

32

积分

注册会员

Rank: 2

积分
32
发表于 2008-12-15 13:49:00 | 显示全部楼层

Re: 关于0xC0000005: 读取位置 0x00000004 时发生访问冲突 的问题

这个问题我也遇过,但不知道跟你的一不一样。
我是在别人的机子上运行都没事,一到自己的机子上运行就出现那种情况。
这个问题让我郁闷了好几天,问了很多人都没能解决。
后来乱搞,就莫名奇妙的解决了。
我是在VS2008下编译的。
点击项目的右键属性-》配置属性-》链接器-》常规-》输出文件
把那个编译器的默认值改掉,例如改成.\Debug/Main.exe
我是这样解决的。
不知道对你有帮助没有。
不过我还没有体会到为什么会这样。 [em1]

0

主题

4

帖子

8

积分

新手上路

Rank: 1

积分
8
发表于 2008-12-23 16:30:00 | 显示全部楼层

Re:关于0xC0000005: 读取位置 0x00000004 时发生访问冲突 的问题

这代码看着真眼熟....
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-20 15:35

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表