Мой код нестабилен: иногда все нормально, и иногда выдает память ошибок чтения/записи или _CrtIsValidHeapPointer. Когда я запускаю программу в "Release build", она вылетает во втором повторении действий, описанных в main(). Но когда его запуск в режиме "Debug" в "Release build" с точками останова при каждом действии - все работает нормально даже после три итерации main(). Тем не менее, нет стабильности. Я не знаю, что с этим случилось. Помоги пожалуйста.
PS Я воссоздаю вопрос.
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();
}
Пробовал здесь (g++ 4.8.2 - cygwin) нет аварии. Проверьте этот комментарий за хорошее предложение, связанное с вашим сбоем.
Но что вы пытаетесь сделать?
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!
capacity()
не должна изменяться на ноль. Это изменится, только если вы reserve()
, если вы используете shrink_to_fit () или если вы используете push_back()
когда size() == capacity()
.
Попробуйте запустить приложение под Valgrind - это действительно объясняет большинство типичных проблем.
uint8 *testBuf; testBuf = malloc(70000*sizeof(uint8));
для выделения массива и посмотреть, исчезнет ли проблема.