Skip to content

Net::load_param 中 continue 导致空指针崩溃与内存泄漏 #6382

@Cat-myq

Description

@Cat-myq

问题背景

在 ncnn 的 Net::load_param(const DataReader& dr) 函数中,当层参数解析(ParamDict::load_param)或层加载(Layer::load_param)失败时,代码通过 continue 跳过当前层继续执行。该逻辑存在两个关键问题,在实际场景中会引发崩溃和资源泄漏。

具体问题

1. 空指针崩溃风险

d->layersresize(layer_count) 初始化后,每个元素默认是 nullptr
当触发 continue 时,会跳过 d->layers[i] = layer 赋值步骤,导致 d->layers[i] 始终保持 nullptr
后续流程访问到d->layers[i] 时会访问该空指针,直接触发崩溃。

2. 内存泄漏

layer 实例通过 create_overwrite_builtin_layer/create_layer_cpu 等函数动态分配。
continue 未释放该 layer 指针,且未将其存入 d->layers,导致这部分内存永远无法回收,长期运行会耗尽设备内存。

影响场景

  • 必现场景:param 文件损坏(如刻意破坏某层 key-value 格式),触发 ParamDict load_paramlayer load_param 失败时,后续访问空指针崩溃。
  • 偶现场景:Android 设备 IO 波动(如内存不足、存储介质延迟)导致 param 文件读取后内容异常,解析失败触发相同问题,这也是部分机型偶发崩溃的潜在诱因。

补充说明

模型加载是依赖强关联的流程,任何一层加载失败都会导致后续推理逻辑断裂。相比 continue 掩盖错误,return -1 能让上层业务及时感知加载失败,感觉更符合实际使用场景的预期。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions