[Внимание: я прочитал существующие потоки в StackOverflow. Нет, похоже, на мой вопрос]C++ bad_alloc вызвано новым?
Я смотрю в формате Quake 2 MD2. Кажется, я получаю плохое выделение после добавления указателя-массива. Однако, если я делаю некоторые ужасные манипуляции с указателями, все в порядке. Я думаю, вопрос в том, почему я получаю такое исключение?
Работает первая «MD2Model :: Load». Тот, который я опубликовал после получения исключения.
Основные структуры:
struct MD2Header
{
int nIdentifier;
int nVersion;
int nSkinWidth;
int nSkinHeight;
int nFrameSize;
int nNumSkins;
int nNumVertices;
int nNumUV;
int nNumTriangles;
int nNumCmds;
int nNumFrames;
int nOffsetSkins;
int nOffsetUV;
int nOffSetTriangles;
int nOffsetFrames;
int nOffsetCmds;
int nOffsetEnd;
};
struct MD2Skin
{
char szName[64];
};
struct MD2TexCoord
{
short t;
short u;
};
struct MD2Triangle
{
short nVertex[3];
short tu[3];
};
struct MD2Vertex
{
float fVertex[3];
float fNormal[3];
};
struct MD2Frame
{
char szName[16];
MD2Vertex* pVerts;
};
И теперь, функция, которая считывает файл .md2:
bool MD2Model::Load(const char* pszName)
{
FILE* pFile = NULL;
fopen_s(&pFile, pszName, "rb");
if(!pFile)
return false;
/* Read Header */
fread(&m_Header, sizeof(MD2Header), 1, pFile);
/* Allocate Pointers */
m_pSkins = new MD2Skin[m_Header.nNumSkins];
m_pTexCoords = new MD2TexCoord[m_Header.nNumUV];
m_pTriangles = new MD2Triangle[m_Header.nNumTriangles];
m_pFrames = new MD2Frame[m_Header.nNumFrames];
/* Read Skins */
fseek(pFile, m_Header.nOffsetSkins, SEEK_SET);
fread(m_pSkins, sizeof(MD2Skin), m_Header.nNumSkins, pFile);
/* Read Texture Coords */
fseek(pFile, m_Header.nOffsetUV, SEEK_SET);
fread(m_pTexCoords, sizeof(MD2TexCoord), m_Header.nNumUV, pFile);
/* Read Faces */
fseek(pFile, m_Header.nOffSetTriangles, SEEK_SET);
fread(m_pTriangles, sizeof(MD2Triangle), m_Header.nNumTriangles, pFile);
/* Read Animations */
struct stMD2Vertex
{
unsigned char nVertex[3];
unsigned char nLightNormalIndex;
};
struct stMD2Frame
{
float fScale[3];
float fTranslate[3];
char szName[16];
stMD2Vertex verts[1];
};
unsigned char pBuffer[30000];
stMD2Frame* pTmp = (stMD2Frame*) pBuffer;
fseek(pFile, m_Header.nOffsetFrames, SEEK_SET);
for(int i = 0; i < m_Header.nNumFrames; i++)
{
fread(pTmp, 1, m_Header.nFrameSize, pFile);
m_pFrames[i].pVerts = new MD2Vertex[m_Header.nNumVertices];
strcpy_s(m_pFrames[i].szName, pTmp->szName);
for(int j = 0; j < m_Header.nNumVertices; j++)
{
m_pFrames[i].pVerts[j].fVertex[0] = pTmp->verts[j].nVertex[0] *
pTmp->fScale[0] + pTmp->fTranslate[0];
m_pFrames[i].pVerts[j].fVertex[2] = -1 * (pTmp->verts[j].nVertex[1] *
pTmp->fScale[1] + pTmp->fTranslate[1]);
m_pFrames[i].pVerts[j].fVertex[1] = pTmp->verts[j].nVertex[2] *
pTmp->fScale[2] + pTmp->fTranslate[2];
}
}
return true;
}
Переменные сбрасывали во время отладки:
nNumSkins 1 int
nNumVertices 583 int
nNumUV 582 int
nNumTriangles 422 int
nNumFrames 1 int
(я кончался удаление мои структуры D3DXVECTOR3, чтобы посмотреть, так что это неистово.)
Хорошо. Итак, внутри цикла «for», где он взрывается. Если бы я сделать это следующим образом:
// unsigned char pBuffer[30000];
// stMD2Frame* pTmp = (stMD2Frame*) pBuffer;
fseek(pFile, m_Header.nOffsetFrames, SEEK_SET);
for(int i = 0; i < m_Header.nNumFrames; i++)
{
stMD2Frame* pTmp = new stMD2Frame();
fread(pTmp, 1, m_Header.nFrameSize, pFile);
m_pFrames[i].pVerts = new MD2Vertex[m_Header.nNumVertices];
strcpy_s(m_pFrames[0].szName, pTmp->szName);
я получаю исключение bad_alloc при распределении «m_pFrames [я] .pVerts» заявление. Иногда я этого не понимаю, но я получаю исключение, когда я пытаюсь создать новый класс D3D (я предполагаю, что я получу его независимо от того, что я потом буду потом). Мое использование MEM чрезвычайно низкое, так что это может быть куча коррупции?
На самом деле мне приходилось делать это во время создания моего VertexBuffer во время анимации.
Должен ли я использовать векторы? Я знаю, что они выделяют больше, чем нужно, но это кажется (наиболее очевидным) [лучшим] способом.
'bad_alloc' обычно вызывается, когда вы исчерпываете память. Попытайтесь контролировать использование памяти вашей программой и «удалять» память, как только она вам больше не понадобится. –
Возможно, вы просто переполняете свой pBuffer и записываете в число циклов i, и это просто останавливает цикл от завершения. –
Сделать глобальную переменную и увидеть, если поведение изменится ... –