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

malloc内存泄漏警告排查:copyMemZone测试代码问题分析

内存泄漏警告分析与代码问题修正

这个警告的提示位置有点偏差,但核心指出的风险是真实存在的,同时你的代码还有其他潜在问题,下面具体拆解:

一、警告的真实原因

虽然clang-analyzer把警告标在了dataDest的malloc行,但实际问题出在**dataSource的潜在泄漏**:

  • 当dataDest分配失败时,你直接return EXIT_FAILURE,此时dataSource已经完成内存分配,但没有被free,这就触发了分析器的泄漏检测。
  • 分析器的提示行错位,是因为它跟踪到泄漏的根源和dataDest的分配分支有关,所以指向了这行代码,但警告的核心(dataSource可能泄漏)是对的。

二、代码里的其他问题

  • 缓冲区溢出风险:copyMemZone函数完全没检查目标缓冲区的大小是否够装要复制的内容。如果sizeMaxDest小于endMemo - beginMemo,写数据的时候会直接越界,触发未定义行为。
  • 类型不匹配:main里的beginMemo、endMemo是int(有符号),但copyMemZone的参数是size_t(无符号),要是传个负数进去,逻辑直接乱套。
  • 冗余强制转换:copyMemZone((unsigned char*)dataSource,...)里的强制转换完全多余,dataSource本身就是unsigned char*类型。

三、修正后的代码

#include <cstdlib>
#include <QDebug>

int copyMemZone(unsigned char* zoneSourceFonc, size_t debutSourceFonc, size_t finSourceFonc, unsigned char** zoneDestFonc, size_t destBufferSize);
int copyMemZone(unsigned char *zoneSourceFonc, size_t debutSourceFonc, size_t finSourceFonc, unsigned char **zoneDestFonc, size_t destBufferSize)
{
    // 先校验参数合法性
    if (!zoneSourceFonc || !zoneDestFonc) return EXIT_FAILURE;
    if (debutSourceFonc >= finSourceFonc) return EXIT_SUCCESS;

    size_t copySize = finSourceFonc - debutSourceFonc;
    // 检查目标缓冲区是否足够
    if (copySize > destBufferSize) return EXIT_FAILURE;

    // 简化复制逻辑
    for (size_t i = 0; i < copySize; ++i)
    {
        (*zoneDestFonc)[i] = zoneSourceFonc[debutSourceFonc + i];
    }

    return EXIT_SUCCESS;
}

int main()
{
    const size_t sizeSource = 10;                     // 统一用size_t处理内存相关的数值
    const size_t beginMemo = 2, endMemo = 8;
    const size_t sizeMaxDest = 10;

    unsigned char* dataSource = static_cast<unsigned char*>(malloc(sizeSource * sizeof(unsigned char)));
    if (!dataSource) {
        return EXIT_FAILURE;
    }

    // 初始化数据源
    dataSource[0] = '0';
    dataSource[1] = 'X';
    dataSource[2] = 'M';
    dataSource[3] = 'E';
    dataSource[4] = 'M';
    dataSource[5] = 'O';
    dataSource[6] = 'R';
    dataSource[7] = 'Y';
    dataSource[8] = '8';
    dataSource[9] = '7';

    unsigned char* dataDest = static_cast<unsigned char*>(malloc(sizeMaxDest * sizeof(unsigned char)));
    if (!dataDest) {
        free(dataSource); // 分配失败时先释放已申请的dataSource
        return EXIT_FAILURE;
    }
    const size_t tailleDest = endMemo - beginMemo;

    if (copyMemZone(dataSource, beginMemo, endMemo, &dataDest, sizeMaxDest) != EXIT_SUCCESS) {
        qDebug() << "内存区域复制失败";
    }

    // 输出复制结果
    for (size_t i = 0; i < tailleDest; ++i) {
        qDebug() << QChar(dataDest[i]);
    }

    // 释放所有内存
    free(dataDest);
    free(dataSource);

    return EXIT_SUCCESS;
}

四、关键修正点

  • 修复了dataSource的泄漏问题:当dataDest分配失败时,先释放dataSource再退出。
  • 给copyMemZone加了目标缓冲区大小参数,彻底避免越界访问。
  • 把所有内存相关的变量换成size_t类型,消除符号不匹配的隐患。
  • 增加了参数合法性校验,让代码更健壮。

内容的提问来源于stack exchange,提问作者Juan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 04:08:14