2013-11-27 4 views
1

[Внимание: я прочитал существующие потоки в 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 во время анимации.

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

+0

'bad_alloc' обычно вызывается, когда вы исчерпываете память. Попытайтесь контролировать использование памяти вашей программой и «удалять» память, как только она вам больше не понадобится. –

+0

Возможно, вы просто переполняете свой pBuffer и записываете в число циклов i, и это просто останавливает цикл от завершения. –

+0

Сделать глобальную переменную и увидеть, если поведение изменится ... –

ответ

2

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

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

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

EDIT

Глядя снова, я думаю, что проблема в том, что вы определяете, как 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 

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

+0

Я трижды проверил это. Документация говорит о завершении с нулевой отметкой, как и отладчик. Кроме того, перед этим возникает сообщение bad_alloc, при распределении m_pFrames [i] .pVert. – user3043262

+0

@ user3043262 Хороший вопрос - я добавил еще одну возможность –

+0

, что вы здорово! Я этого не понимал! Теперь, чтобы убрать мой код и получить 15 очков, чтобы я мог голосовать. – user3043262

Смежные вопросы