Android C++中AAsset_read读取资源文件出现数据混淆问题求助
Android Assets读取文件内容混入问题解决
问题原因
你读取文件的代码存在两个关键问题:
- 文件内容本身不包含C风格字符串的终止符
\0,但你用std::string(bits)构造字符串时,该构造函数会从bits指针开始读取,直到遇到内存中的第一个\0才停止。如果之前读取第一个文件的内存区域未被完全覆盖,残留数据就会被混入当前字符串。 - 原代码中
new char[size]分配的内存未释放,存在内存泄漏风险。
修复方案
方案一:手动添加字符串终止符
修改缓冲区分配逻辑,多留一个字节存储\0,确保构造std::string时能正确识别字符串边界:
std::string Assets::getTextFile(const char *file) { AAsset *asset = AAssetManager_open(android_assetManager, file, AASSET_MODE_UNKNOWN); int size = AAsset_getLength(asset); char *bits = new char[size + 1]; // 多分配1字节用于存储终止符 AAsset_read(asset, bits, size); bits[size] = '\0'; // 手动添加字符串终止符 AAsset_close(asset); std::string a(bits); delete[] bits; // 释放缓冲区内存,避免泄漏 return a; }
方案二:直接利用std::string的长度构造(更推荐)
跳过手动分配char缓冲区,直接使用std::string预先分配空间并写入,无需处理终止符,同时自动管理内存:
std::string Assets::getTextFile(const char *file) { AAsset *asset = AAssetManager_open(android_assetManager, file, AASSET_MODE_UNKNOWN); int size = AAsset_getLength(asset); std::string content(size, '\0'); // 预先分配指定长度的字符串 AAsset_read(asset, content.data(), size); // 直接写入字符串的内部缓冲区 AAsset_close(asset); return content; }
额外说明
- AASSET_MODE_UNKNOWN模式在此场景下可以正常使用,若需要优化读取性能,可根据文件大小考虑换成
AASSET_MODE_BUFFER(将文件全部加载到内存)或AASSET_MODE_STREAMING(流式读取)。 - 两种方案都解决了内存泄漏问题,方案二无需手动管理内存,代码更简洁安全。
内容的提问来源于stack exchange,提问作者user1063364
相关产品推荐
相关产品推荐

