如何解决EXC_BAD_ACCESS-C ++ substr函数
我有一个使用c ++ substr的函数。在Linux和macOS上,此功能有时会在程序末尾(从单独的线程调用时)随机崩溃。
功能如下:
bool mkpath( string path )
{
bool bSuccess = false;
int nRC = ::mkdir( path.c_str(),0775 );
if( nRC == -1 )
{
switch( errno )
{
case ENOENT:
//parent didn't exist,try to create it
if( mkpath( path.substr(0,path.find_last_of('/')) ) )
{
//Now,try to create again.
int status = ::mkdir( path.c_str(),0775 );
bSuccess = (0 == status || errno == EEXIST);
}
else
{
bSuccess = false;
}
break;
case EEXIST:
//Done!
bSuccess = true;
break;
default:
bSuccess = false;
break;
}
}
else
bSuccess = true;
return bSuccess;
}
lldb回溯如下:
* thread #4,stop reason = EXC_BAD_ACCESS (code=2,address=0x70000097fff8)
* frame #0: 0x00007fff73d2a81a libsystem_malloc.dylib`tiny_malloc_from_free_list + 8
frame #1: 0x00007fff73d2a297 libsystem_malloc.dylib`tiny_malloc_should_clear + 288
frame #2: 0x00007fff73d290c6 libsystem_malloc.dylib`szone_malloc_should_clear + 66
frame #3: 0x00007fff73d27d7a libsystem_malloc.dylib`malloc_zone_malloc + 104
frame #4: 0x00007fff73d27cf5 libsystem_malloc.dylib`malloc + 21
frame #5: 0x00007fff70ea0dea libc++abi.dylib`operator new(unsigned long) + 26
frame #6: 0x00007fff70e73d70 libc++.1.dylib`std::__1::basic_string<char,std::__1::char_traits<char>,std::__1::allocator<char>
>::basic_string(std::__1::basic_string<char,std::__1::allocator<char> > const&,unsigned long,std::__1::allocator<char>
const&) + 132
frame #7: 0x0000000103821467 libSampleLibrary.dylib`std::__1::basic_string<char,std::__1::allocator<char> >::substr(unsigned long,unsigned
long) const + 87
frame #8: 0x0000000103820c77 libSampleLibrary.dylib`mkpath(std::__1::basic_string<char,std::__1::allocator<char> >) + 135
frame #9: 0x0000000103820c80 libSampleLibrary.dylib`mkpath(std::__1::basic_string<char,std::__1::allocator<char> >) + 144
frame #10: 0x0000000103820c80 libSampleLibrary.dylib`mkpath(std::__1::basic_string<char,std::__1::allocator<char> >) + 144
frame #11: 0x0000000103820c80 libSampleLibrary.dylib`mkpath(std::__1::basic_string<char,std::__1::allocator<char> >) + 144
frame #12: 0x0000000103820c80 libSampleLibrary.dylib`mkpath(std::__1::basic_string<char,std::__1::allocator<char> >) + 144
frame #13: 0x0000000103820c80 libSampleLibrary.dylib`mkpath(std::__1::basic_string<char,std::__1::allocator<char> >) + 144
frame #14: 0x0000000103820c80 libSampleLibrary.dylib`mkpath(std::__1::basic_string<char,std::__1::allocator<char> >) + 144
frame #15: 0x0000000103820c80 libSampleLibrary.dylib`mkpath(std::__1::basic_string<char,std::__1::allocator<char> >) + 144
...
发生这种情况的任何可能原因?像我们添加的那样,可以从外部取消调用该线程的线程
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
在函数的第一行,从该函数被调用。
无论何时发生此崩溃,我都会在回溯中看到以下行超过5400次,这非常令人惊讶:
frame #15: 0x0000000103820c80 libSampleLibrary.dylib`mkpath(std::__1::basic_string<char,std::__1::allocator<char> >) + 144
我进一步调试,结果发现一个静态变量(homePath)被破坏(返回垃圾)。 mkpath()函数从以下函数获取它的值:
string GetSettingFilePath()
{
static string homePath = "";
if(!homePath.empty()){
// sometimes homePath variable returns junk at the program exit
return homePath;
}
struct passwd* pwd = getpwuid(getuid());
if (pwd)
{
homePath = pwd->pw_dir;
}
else
{
// try the $HOME environment variable
homePath = getenv("HOME");
}
if (homePath.empty())
{
homePath = "./";
}
return homePath
}
由于尽管正确设置了homePath变量,有时它会在程序退出时返回垃圾,所以会导致无限递归。但是,为什么在程序出口调用该函数时,该函数内部的静态变量会返回垃圾。
解决方法
如果您递归调用mkpath
,而path
中的字符串 中没有斜杠/
。那么您将拥有无限递归。
递归将是无限的,因为您将使用与调用时完全相同的参数调用mkpath
。
在进行递归调用之前,应检查path
是否真的有斜杠/
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。