内存读/写acсess错误异常

时间:2014-01-03 19:38:14

标签: c++ memory memory-management

我的代码不稳定:有时一切都很好,有时会抛出错误内存读/写或_CrtIsValidHeapPointer。当我在'Release build'中运行程序时,它在main()中描述的动作的第二次重复时崩溃但是当它在'Release build'中运行'Debug mode'并且在每个动作上都有断点时 - 一切都工作正常main()的三次迭代。仍然没有稳定性。我不知道 - 这有什么不对。求助。

P上。 S.我重新创建问题帖子。

Main.cpp的

int main(...)
{
    // ...
    std::vector<CResource> m_aRes;
    uint8 testBuf[70000];

    m_aRes.push_back(CResource(70000));
    m_aRes.back().SetName("Test Name");
    m_aRes.back().SetType("Test Type");
    m_aRes.back().AppendData(testBuf, 70000);
    // ...
}

CResource.h

class CResource
{
protected:
    std::string m_sName;    
    std::string m_sSubName; 
    std::string m_sType;

    std::vector<uint8> m_Data;
UINT               m_DataLen;
public:
    CResource(UINT size);
    ~CResource();   

    void          SetName(char * name);
    void          SetType(char * type);
    const char *  GetName(void);
    const char *  GetType(void);
    const char *  GetSubName(void);
    bool          IsWhole(void);
    UINT          AppendData(uint8 * data, UINT len);
    uint8 *       GetData(void);
    UINT          GetDataLen(void);
    UINT          GetDataLenTemp(void);
};

CResource.cpp

CResource::CResource(UINT size)
{
    m_sName.clear();
    m_sSubName.clear(); 
    m_sType.clear();    

    m_DataLen = size;
    m_Data.reserve(m_DataLen);
}
CResource::~CResource()
{   
    m_sName.clear();
    m_sName.shrink_to_fit();
    m_sSubName.clear();
    m_sSubName.shrink_to_fit();
    m_sType.clear();
    m_sType.shrink_to_fit();    

    m_Data.clear();
    m_Data.shrink_to_fit(); 
}

void CResource::SetName(char * name)
{
    if(!name) return;

    m_sSubName.clear();
    m_sName = name;

    bool bSubNameFound = false;
    for(UINT i=m_sName.size(); i>0; i--) {
            if(bSubNameFound)
                    m_sSubName.insert(0 , &m_sName[i - 1]);
            if(m_sName[i] == '/')
                    bSubNameFound = true;
    }
}
void CResource::SetType(char * type)
{
    if(!type) return;

    m_sType = type;
}
const char * CResource::GetName(void) 
{ 
    return m_sName.c_str(); 
}
const char * CResource::GetType(void)
{ 
    return m_sType.c_str(); 
}
const char * CResource::GetSubName(void) 
{ 
    return m_sSubName.c_str();
}
bool CResource::IsWhole(void) 
{
    return (m_DataLen > 0 && m_DataLen == m_Data.size()) ? true : false; 
}
UINT CResource::AppendData(uint8 * data, UINT len)
{
    if(!data || !len || IsWhole() || m_DataLen == 0) return NULL;   

    UINT DataLenApp = m_Data.size() + len;

    if(DataLenApp > m_DataLen)                   
    {                                               
            len = m_DataLen - m_Data.size();             
            DataLenApp = m_DataLen;                     
    }   

    UINT nFirstApp = m_Data.size();
    for(UINT i = nFirstApp; i < DataLenApp; i++)
                m_Data.push_back(data[i - nFirstApp]);

    return len;
}
uint8 * CResource::GetData(void) 
{ 
    return m_Data.data(); 
}
UINT CResource::GetDataLen(void) 
{
    return m_DataLen; 
}
UINT CResource::GetDataLenTemp(void) 
{ 
    return m_Data.size();
}

2 个答案:

答案 0 :(得分:1)

在这里尝试(g ++ 4.8.2 - cygwin)没有崩溃。检查this comment以获取与您的崩溃有关的好建议。

但是,你想做什么?

m_DataLen = size;
m_Data.reserve(m_DataLen);

m_DataLen似乎是m_Data.capacity()的同义词。

这里你禁止重新分配数组(IsWhole检查m_Data.size()不等于m_DataLen

if(!data || !len || IsWhole() || m_DataLen == 0) return NULL; 

您应该至少简化检查,避免使用m_DataLen的双重定义并使用m_Data.capacity()

顺便说一句,以下代码似乎没有错,但比需要的要复杂得多:

UINT nFirstApp = m_Data.size();
for(UINT i = nFirstApp; i < DataLenApp; i++)
   m_Data.push_back(data[i - nFirstApp]);

基本上是:

m_Data.insert(m_Data.end(), data, data + (DataLenApp - nFirstApp));

所以我的经验法则是:简化代码并使用STD提供的内容!

答案 1 :(得分:0)

尝试在Valgrind下运行您的应用程序 - 真的解释了大多数典型问题。