You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android C++中AAsset_read读取资源文件出现数据混淆问题求助

Android Assets读取文件内容混入问题解决

问题原因

你读取文件的代码存在两个关键问题:

  1. 文件内容本身不包含C风格字符串的终止符\0,但你用std::string(bits)构造字符串时,该构造函数会从bits指针开始读取,直到遇到内存中的第一个\0才停止。如果之前读取第一个文件的内存区域未被完全覆盖,残留数据就会被混入当前字符串。
  2. 原代码中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:12:40