массивы — C ++ bad_alloc вызвано новым?

[Примечание: я прочитал существующие темы в StackOverflow. Похоже, никто не ответил на мой вопрос.]

Я смотрю в формате 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 [i] .pVerts».
Иногда я не получаю это, но я получаю исключение, когда пытаюсь обновить свой класс D3D (я предполагаю, что получу это независимо от того, что я буду новым после этого).
Мое использование MEM чрезвычайно низкое, так может ли это быть повреждение кучи?

Я действительно должен был сделать это во время создания моего VertexBuffer во время анимации.

Должен ли я в конечном итоге использовать векторы? Я знаю, что они выделяют больше, чем нужно, но это кажется (наиболее очевидным) [лучшим] способом.

1

Решение

Я бы проверил строку:

strcpy_s( m_pFrames[0].szName, pTmp->szName );

Если строка, загруженная из файла, не заканчивается нулем, эта копия может в конечном итоге перезаписать пространство стека и привести к повреждению.

РЕДАКТИРОВАТЬ

Опять же, я думаю, что проблема в том, что вы определяете stMD2Frame как

struct stMD2Frame
{
float fScale[3];
float fTranslate[3];
char szName[16];
stMD2Vertex verts[1];
};

но это имеет место только для одной вершины.

Когда вы читаете в кадре как

fread( pTmp, 1, m_Header.nFrameSize, pFile );

ты испортишь свою память

Я предлагаю проверить, что

sizeof(stMD2Frame)>=m_Header.nFrameSize

перед чтением данных.

2

Другие решения

Других решений пока нет …

А ты уже прошел курс программирования? Супер скидка!
Прокачать скилл $$$
×