ue4环境下,项目需要下载热更文件到本地,但是怪事出现了,编辑器PIE中运行良好的代码,打包后稳定崩溃。
经检查dmp文件,崩溃发生在输出流ofstream的close函数中。
TArraysaveData = 服务器http响应的body; std::ofstream* file = new std::ofstream("文件名"); file << (const char*)saveData.getData(); file.close();//崩溃
提前说下,ue4的TArray类似于std::vector,uint8 即 unsigned char
观察写入的文件发现,文件末尾会意外的出现随机字符。
VS的调试器无法解析saveData信息,显示为无效的字符串
在同事的不懈努力(各种写入方法穷举尝试)
发现将<<运算符替换为file.write() 方法后即可修复崩溃问题。
通过打印日志后发现
Log(saveData.Num(),strlen((const char*)saveData.getData()));// Log:37650,37686
确认异常为strlen()引发,观察对内存数据发现,
saveData[saveData.Num() - 1] == ‘m’
众所周知,strlen的经典实现方式(未进行任何优化)
size_t strlen(const char* str)
{
size_t size = 0;
while(*(str + size) != ' ')
{
++size;
}
return size;
}
默认是以’ ’为字符串的结束标志,若该字符串中不包含这个结束符,则返回的值可能会远大于实际字符串长度,当流写入时,导致数组访问越界,最终导致崩溃。
解决方案很简单
file.write((const char*)saveData.getData(),saveData.Num());
file.close();
//或
saveData.Add(' ');
file << (const char*)saveData.getData();
file.close();
显然第一种方案更好,避免了动态数据的空间增长的可能。
至于PIE模式下为什么不会崩溃,这就可能要问msvc的Debug模式了



