падение в (оператор new (без знака int) +22) - PullRequest
1 голос
/ 07 марта 2019

я пытаюсь найти причину следующего сбоя на андроиде:

сбой в (оператор новый (unsigned int) +22)

это значитчто память не была выделена успешно?и если да, то добавление std :: nothrow и проверка нуля и выход из программы - правильное решение?

есть ли способ ограничить выделение программы для ее воспроизведения?

код, где происходит сбой:

glCompileShader( VSID );

GLint vstat;
glGetShaderiv( VSID, GL_COMPILE_STATUS, &vstat );

if( vstat != GL_TRUE )
{
    GLint infolen;
    glGetShaderiv( VSID, GL_INFO_LOG_LENGTH, &infolen );

    GLchar* infostring = new GLchar[infolen + 1];

    glGetShaderInfoLog( VSID, infolen, nullptr, infostring );
    infostring[infolen] = 0;

    std::stringstream Error;
    Error << "An Error occured while trying to compile"\
        " Vertex Shader \"" << VertexShaderPath
        << "\":\n\n" << infostring;
}

Ответы [ 2 ]

4 голосов
/ 07 марта 2019

Сбой в операторе new или new[] может быть вызван:

  • неудачное размещение. Например, если infolen слишком велико по сравнению с доступной памятью.
  • сбой в конструкторе выделяемого объекта (ов). Но с GLchar это не очень вероятно.

Вы должны добавить код для обработки исключения, заключив новый в блок try .. catch (как показано здесь ), чтобы завершить его любезно.

Если вы вызываете new с nothrow, вам следует проверить, что возвращаемый указатель отличается от nullptr, чтобы избежать неприятных UB.

2 голосов
/ 07 марта 2019

Я вижу две проблемы с вашим кодом: во-первых, вы не проверяете, успешно ли glGetShaderiv или нет;если нет, то infolen остается неинициализированным.Меньше проблем, и только проблема при работе в среде с ошибками состоит в том, что вы не используете указатель length glGetShaderInfoLog для добавления нулевого терминатора в конце;всегда полезно получить это значение, а также проверить согласованность.

Также я предлагаю вам использовать std::string вместо ручного выделения:

std::string infostring;
while( GL_NO_ERROR != glGetError() ); /* Flush Errors */

GLenum err;
glCompileShader( VSID );
if( GL_NO_ERROR == (err = glGetError())
){
    GLint vstat = 0;
    glGetShaderiv( VSID, GL_COMPILE_STATUS, &vstat );

    if( (GL_NO_ERROR == (err = glGetError()))
     && vstat != GL_TRUE
    ){
        GLint infolen = 0;
        glGetShaderiv( VSID, GL_INFO_LOG_LENGTH, &infolen );
        if( (GL_NO_ERROR == (err = glGetError()))
         && 0 < infolen
        ){
            GLsizei returned_infolen = 0;
            infostring = std::string(infolen, 0);
            glGetShaderInfoLog( VSID, infolen, &returned_infolen, infostring.data() );
            infostring.resize(returned_infolen);

            err = glGetError();
    }
}
if( GL_NO_ERROR != err
){
       std::stringstream Error;
        Error << "An Error occured while trying to compile"\
            " Vertex Shader \"" << VertexShaderPath
            << "\":\n\n" << infostring;
}
...