在 (operator new(unsigned int)+22) 处崩溃
crash at (operator new(unsigned int)+22)
我正在尝试找出 android 上报告的以下崩溃的原因:
崩溃于(operator new(unsigned int)+22)
是不是内存分配不成功?如果是这样,添加 std::nothrow 和 null 检查并退出程序是正确的解决方案吗?
有什么方法可以限制程序不分配以便重现它?
崩溃的代码:
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;
}
运算符 new
or new[]
中的崩溃可能由以下原因引起:
- 分配失败。例如,如果
infolen
与可用内存相比太大。
- 正在分配的对象的构造函数发生崩溃。但是对于
GLchar
,这不太可能。
您应该添加代码来处理异常,方法是将 new 包含在 try
..catch
块中(如 here 所示),以便优雅地终止。
如果你用 nothrow
调用 new 你应该检查返回的指针是否不同于 nullptr
以避免讨厌的 UB。
我发现您的代码有两个问题:首先,您没有检查 glGetShaderiv
是否成功;如果不是,则 infolen
保持未初始化状态。如果 运行 在有问题的环境中,那么问题不大,只有一个问题是,您没有使用 glGetShaderInfoLog
的 length
指针在末尾添加空终止符;检索该值以及一致性检查始终是一个好习惯。
此外,我建议您使用 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;
}
我正在尝试找出 android 上报告的以下崩溃的原因:
崩溃于(operator new(unsigned int)+22)
是不是内存分配不成功?如果是这样,添加 std::nothrow 和 null 检查并退出程序是正确的解决方案吗?
有什么方法可以限制程序不分配以便重现它?
崩溃的代码:
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;
}
运算符 new
or new[]
中的崩溃可能由以下原因引起:
- 分配失败。例如,如果
infolen
与可用内存相比太大。 - 正在分配的对象的构造函数发生崩溃。但是对于
GLchar
,这不太可能。
您应该添加代码来处理异常,方法是将 new 包含在 try
..catch
块中(如 here 所示),以便优雅地终止。
如果你用 nothrow
调用 new 你应该检查返回的指针是否不同于 nullptr
以避免讨厌的 UB。
我发现您的代码有两个问题:首先,您没有检查 glGetShaderiv
是否成功;如果不是,则 infolen
保持未初始化状态。如果 运行 在有问题的环境中,那么问题不大,只有一个问题是,您没有使用 glGetShaderInfoLog
的 length
指针在末尾添加空终止符;检索该值以及一致性检查始终是一个好习惯。
此外,我建议您使用 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;
}