私のコードは不安定です。すべてが正常な場合もあれば、エラーメモリの読み取り/書き込みまたは_CrtIsValidHeapPointerがスローされる場合もあります。「リリースビルド」でプログラムを実行すると、メイン()で説明されているアクションの2回目の繰り返しでクラッシュしますが、「リリースビルド」の「デバッグモード」で実行すると、すべてのアクションにブレークポイントがあります-その後もすべて正常に動作しますmain()の3回の反復。まだ安定性がありません。わかりません-何が問題なのですか。助けてください。
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が提供するものを使用してください!
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加