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

Criterion框架字符串参数化测试崩溃问题及原因咨询

Criterion框架字符串参数化测试崩溃问题及原因咨询

咱们先拆解你遇到的问题:同样是参数化测试,int类型能正常跑,字符串版本却直接崩溃,后来用cr_malloc复制字面量就好了——核心原因其实是字符串字面量的存储特性和Criterion框架的内存管理逻辑不匹配。

一、第一个测试崩溃的根本原因

你最初的代码里,这段定义的字符串指针数组存在关键问题:

// 这里的指针指向只读段的字符串字面量
static char* strings[] = {"Foo", "Bar"};
return cr_make_param_array(char*, strings, strings_count);

"Foo"、"Bar"属于字符串字面量,这类数据在程序编译时就被放到了只读数据段(.rodata)里,这块内存是受系统保护的,既不能修改,也不能用free(或者Criterion的cr_free)去释放。

而Criterion的参数化测试框架,对于指针类型的参数(比如你这里的char*),会默认在每个测试用例执行完毕后,尝试用cr_free去释放参数指向的内存。当框架尝试释放只读段的内存时,就会触发非法内存访问,直接导致程序崩溃——这就是你看到CRASH!的原因。

二、为什么int参数的测试能正常运行?

你的int测试用的是:

static int numbers[] = {1, 2};
return cr_make_param_array(int, numbers, numbers_count);

这里的数组属于静态数据段,而且参数类型是基本类型int。Criterion对基本类型的参数化处理逻辑和指针类型不同:它会直接复制数组里的整数值(或者传递指向静态数组元素的指针,但不会尝试释放静态内存),不需要涉及内存释放操作,所以不会触发错误。

三、你后来的修复方案为什么有效?

你改用cr_malloc在堆上分配字符串内存,再把字面量复制过去:

strings[k] = cr_malloc(strlen(STRINGS[k]) + 1);
strcpy(strings[k], STRINGS[k]);

这时候指针指向的是框架可以管理的堆内存。因为cr_malloc是Criterion配套的内存分配函数,框架会用对应的cr_free来释放这块内存,整个流程符合框架的内存管理规则,所以测试就能正常执行,不会崩溃。

对你疑问的解答

你的假设不完全准确:字符串字面量并不是动态分配的,它们是编译时就确定的静态只读内存。崩溃的原因不是字面量的分配方式,而是框架尝试释放了不属于它管理的只读内存区域。

总结要点

  • 当用Criterion做指针类型的参数化测试时,参数指向的内存必须用cr_malloc/cr_calloc/cr_realloc分配,确保框架能正确管理内存的分配与释放
  • 字符串字面量不能直接作为指针参数使用,因为它们在只读段,无法被框架安全释放
  • 基本类型(int、float等)的参数不需要考虑这个问题,框架会直接处理值的复制,不涉及内存释放操作

备注:内容来源于stack exchange,提问作者Mehdi Charife

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 13:39:30