ue4环境下,项目需要下载热更文件到本地,但是怪事出现了,编辑器PIE中运行良好的代码,打包后稳定崩溃。
经检查dmp文件,崩溃发生在输出流ofstream的close函数中。

	TArray<uint8> saveData = 服务器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) != '\0')
		++size;
	return size;

默认是以’\0’为字符串的结束标志,若该字符串中不包含这个结束符,则返回的值可能会远大于实际字符串长度,当流写入时,导致数组访问越界,最终导致崩溃。

解决方案很简单

	file.write((const char*)saveData.getData(),saveData.Num());
	file.close();
	saveData.Add('\0');
	file << (const char*)saveData.getData();
	file.close();

显然第一种方案更好,避免了动态数据的空间增长的可能。
至于PIE模式下为什么不会崩溃,这就可能要问msvc的Debug模式了

C++语言不直接处理输入输出,而是通过一族定义在标准库中的类型来处理IO。这些类型支持从设备读取数据、向设备写入数据的IO操作,设备可以是文件、控制台窗口等。还有一些类型允许内存IO,即从string读取数据,向string写入数据。 #include&amp;lt;iostream&amp;gt; istream; wistream; ostream; wostream; iostre...
1. 使用ifstream读文件时被截断 ifstream file; 使用文本方式读时,即file.open(filePath, ifstream::in),如果碰到字符0x1A(SUB 换置)时就停止读,后面的内容就被截断了。 使用二进制读可以解决此问题,即 file.open(strFilePath.c_str(), ifstream::in | std::ios::binary);
INT CWriteFileBase::OpenCsvFile(ofstream& of, const CString& strLogFile) of.open(strLogFile, std::ofstream::app); if (!of) return RET_ERR; return RET_OK; 如果已经of.open了没有关闭,再执行of.open会失
关键问题1:如果文件不存在,三种流如何处理? 关键问题2:文件中已有内容,对文件读写时如何控制从何处开始? ps1: fstream头文件不包含有ifstream和ofstream,后者不是前者的子类  ps2: iostream头文件自动包含了istream和ostream,cin 是istream对象,cout是ostream对象 ps3: io流对象不可拷贝、赋值,fstream fs
ofstream奇怪问题解决方法 最近使用ofstream写数据到文件中出现了一些奇怪的问题,发现有时候写入的数据和原始数据不一致,经过观察发现,有些地方多了0D这个东西,查字符 表得知是回车符。因此得知可能是自动插入了回车换行。而且每个0D都在0A前面,这样更加表明ofstream确实会自动在0A前加入0D以表示win下 的回车换行。 解决方法就是使用二进制方式写入,默认是字节流...
c++随笔——linex下无法运行多线程问题 因为pthread 库不是 Linux 系统默认的库,运行时候可以进行连接多线程的外部库,正常编译后面加上 -lphread 就好拉 g++ a1.cpp -o a1 -lpthread 提供个小粒子,给大家实验。。。 #include <iostream> #include <thread> using namespace std; void myprint() cout << "我的线程开始" &lt
在这个示例中,我们使用 `std::ofstream` 类打开一个名为 `output.txt` 的输出文件流,并使用 `<<` 运算符将字符串 "Hello, world!" 写入文件中。注意,在写入完数据后,我们需要使用 `close()` 函数关闭文件流。这是为了确保所有数据都被写入文件并将其保存在磁盘上。最后,我们向控制台输出一条消息,表示数据已经成功写入文件。 需要注意的是,如果打开的文件不存在,则将创建该文件。如果文件已经存在,则会覆盖原有的文件内容。如果您想要在文件末尾添加新的数据而不是覆盖原有的内容,可以使用 `std::ofstream::app` 模式来打开文件流,例如: ```c++ std::ofstream output("output.txt", std::ios::app); 这将以追加模式打开文件流,从而在文件末尾添加新的数据而不是覆盖原有的内容。