这怎么可以解决访问冲突?

时间:2015-08-19 06:43:45

标签: c++ exception

目前,C ++编写的程序抛出一个异常,并在windows下运行。

这是日志中的最小转储信息。

08/12/15 04:37:19 I New Information for UID 2d936a, FloorLoc F1505
08/12/15 04:37:19 E >>>>> EXCEPTION: Access Violation while trying to read address 20203567 
[Fault address:  004AF945 01:000AE945  C:\Program Files (x86)\MySystems\WPR.exe 00400000] <<<<<
Call stack:
Load addr  Address   Frame     Logical addr  Module
00400000   004AF945  0588F8CC  0001:000AE945 C:\Program Files (x86)\MySystems\WPR.exe  
00400000   004A89A4  0588FAEC  0001:000A79A4 C:\Program Files (x86)\MySystems\WPR.exe

根据逻辑地址和.map文件,我可以找到引发此异常的代码。

if (TempMSE->m_elem == NULL)
{
    TempMSE->m_elem = new Element(element);
    TempMSE->m_elem->SetLocation(FloorLoc);
    LoggerInfo("New Information for UID %x, FloorLoc %s", Id, FloorLoc.ToString(buf));
}

TempMSE->m_elem->SetValue0(CIN_0, 0); // this exception is thrown here!!! through logical address 0001:000AE945

似乎m_elemnew运算符获取一个地址,SetLocation函数调用没有异常。以下日志输出也正确。

为什么SetValue0引发了一个例外?这是函数SetValue0

void SetValue0(INDEX idx, DWORD val)    
{ 
    if (idx >= 0 && idx < MAX_INDEX){
        if(val != m_Info[idx]) 
        { 
            m_Info[idx] = val;  
        } 
    }
}

m_InfoElement中的一个数组变量,其大小为MAX_INDEX

另一方面,地址0x20203567似乎是一个可读的地址,怎么会被读取违规?

修改

在此处添加更多信息

class Element {
    // other function here...

private:
    FloorLocation   m_FloorLoc;
    DWORD   m_Info[MAX_INDEX];
    bool            m_Dirty;
};

Element::Element(const Element& elem) {
    m_FloorLoc = elem.m_FloorLoc;
    for (int i = 0; i < MAX_INDEX; ++i)
       m_Info[i] = elem.m_Info[i];
    m_Dirty = elem.m_Dirty;
}

class FloorLocation {
    // other function here...
private:
    FloorId m_floorloc;
};

FloorLocation::FloorLocation( const FloorLocation& loc )
{
    memset(&m_floorloc, ' ', 8); // space filled

    if(loc.m_floorloc.id[0] != 0)
    {
        memcpy(m_floorloc.id, loc.m_floorloc.id, 8);

        // eliminate nulls
        for(int ndx=0; ndx < 8; ndx++)
        {
            if(m_floorloc.id[ndx] == 0)
                m_floorloc.id[ndx]=' ';
        }
    }
}

typedef struct {
    char id[8];
} FloorId;

2 个答案:

答案 0 :(得分:1)

这些问题有点难以回答。我在评论中提出了一些想法,我将在这里详细说明。当我有这些种类的崩溃日志而没有其他线索时,我会寻找这些东西。

在该位置读取的访问冲突建议执行以下操作之一:

  • TempMSE不是有效指针,尝试从中获取m_elem时会抛出异常;

  • TempMSE->m_elem无效,尝试测试SetValue0的值时会在m_Info[idx]内抛出异常。

在后一种情况下,如果您在某处删除TempMSE->m_elem但未将其设置为NULL,则可能会发生这种情况。如果另一个线程负责该删除,可能你在这里有一个竞争条件,它将被设置为NULL,但是这个代码首先被执行。

另一种可能性是TempMSETempMSE->m_elem在此过程中的任何地方都会被破坏。这可能是TempMSE内部缓冲区溢出(如果您有数组)的结果,或者基本上是在内存中这些指针附近发生的任何类型的未定义行为。如果TempMSE在堆栈中,那么在那里寻找任何潜在的麻烦。

我不想用其他类型的猜测(比如堆损坏)来填补这个答案,但希望它能给你一些尝试的途径。常见罪魁祸首的基本清单如下:

  • 编码错误(未初始化或重置值)
  • 线程问题,竞争条件......
  • 未定义的行为或超出垃圾数据
祝你好运!

答案 1 :(得分:1)

我不能说实际上有什么错误,但是我会在0x004AF945处反编译代码 - 以及之前的几条指令,并尝试理解失败函数的哪一部分。

正如其中一条评论所指出的那样,故障发生的地址可疑地看起来像'C# ',这让我觉得某个字符串溢出某个地方......

这只是猜测,但我怀疑TempMSE->m_elem是包含值0x20203567的内容,因此在尝试访问它时不是NULL,这意味着不执行任何日志记录。 [显然这是基于你到目前为止所显示的代码,如果在该节目之前/之后有记录,则不是这种情况,我的第二个猜测是m_info在某种程度上是错误的......