TraverseDirecory--关于递归函数的内存控制
/**
* @brief 遍历一个目录下的所有文件,可递归子目录
* @author soulmachine@gmail.com
* @param[in] pszDirPath 目录的路径,末尾没有'\'
* @param[in] pszFilterPostfix 过滤后缀,如"\\*.*", "\\*.jpg"
* @param[in] bRecursive 是否递归子目录
* @param[in] pfnProcessFile 回调函数指针,用于处理单个文件
* @param[out] pParameter 传递给pfnProcessFile 的参数
* @return 返回文件总数,失败返回-1, 一般失败只发生在第一次 FindFirstFile。
* @note 本函数主要用FindFirstFile,FindNextFile实现。
* @remarks 本函数是用递归版本
*/
int TraverseDirectory(PCTSTR pszDirPath, PCTSTR pszFilterPostfix,
const BOOL bRecursive, int (*pfnProcessFile) \
(PCTSTR pszFilePath, PVOID pParameter), PVOID pParameter)
{
static int nFileCount = 0; //文件总数
WIN32_FIND_DATA findFileData; //保存当前找到的文件的属性
HANDLE hFind = INVALID_HANDLE_VALUE; //FindFirstFile返回的句柄
//当层函数的扫描路径,文件绝对路径或下层函数的目录路径
TCHAR szDirPath[MAX_PATH];
(void)_tcscpy(szDirPath,pszDirPath);
(void)_tcscat(szDirPath, pszFilterPostfix);
hFind = FindFirstFile(szDirPath, &findFileData);
if(INVALID_HANDLE_VALUE == hFind)
{
// FindFirstFile失败的原因:
// 文件夹是坏的
// 没有权限
nFileCount = -1;
ERROR_RETURN(FindFirstFile_Failed);
}
do
{
(void)_sntprintf(szDirPath, (size_t)MAX_PATH, TEXT("%s\\%s"), pszDirPath, findFileData.cFileName);
//如果不是目录
if((DWORD)0 == (findFileData.dwFileAttributes & (DWORD)FILE_ATTRIBUTE_DIRECTORY))
{
nFileCount++;
if(NULL != pfnProcessFile)
{
(void)pfnProcessFile(szDirPath, pParameter);
}
}
//如果是目录,但不是.和..,递归
else if(bRecursive && (findFileData.cFileName[0] != TEXT('.')))
{
(void)TraverseDirectory(szDirPath, pszFilterPostfix, bRecursive, pfnProcessFile, pParameter);
}
else
{
//是.和.. 则什么也不做
}
} while (FALSE != FindNextFile(hFind,&findFileData));
(void)FindClose(hFind);
FindFirstFile_Failed:
return nFileCount;
}我要问的问题是,递归函数的参数,有的是一直不变的,有的是经常变的,比如这里的pszDirPath,每一层调用都不同,而pszFilterPostfix, bRecursive,pfnProcessFile在所有递归层次中都是相同的,但是它们依然占用了一个形参的位置,至少4个字节的空间,每次递归都要为这三个参数分配栈空间,如果递归层次深,这三个参数占用的内存其实是很可观的。
我想到的唯一节省内存的方式是将不经产变的参数合并到一个结构体中,比如,
typedef struct tagPARAMETER
{
PCTSTR pszFilterPostfix;
BOOL bRecursive;
int (*pfnProcessFile) (PCTSTR pszFilePath, PVOID pParameter);
};
这样,原本占三个位置的形参,只占一个了,是原来的1/3。
大家对于“不变”和“易变”的参数是怎么处理的?对于递归函数,有没有更好的办法来节省内存?
相关推荐
基于蒙特卡诺的风、光模型出力(Matlab代码实现)
内容概要:本文详细介绍了基于蒙特卡洛方法的风能与光伏发电出力模型的Matlab代码实现,旨在通过概率统计手段模拟风光发电的不确定性,为电力系统规划与运行提供可靠的数据支持。文中系统阐述了蒙特卡洛模拟的基本原理及其在风、光出力建模中的具体应用,涵盖风速与光照强度的概率分布拟合、随机样本生成、典型场景抽取与削减等关键技术环节,并结合Matlab编程实现了完整的仿真流程,有助于研究人员深入理解可再生能源出力的随机特性及其对电网的影响。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的高校研究生、科研机构研究人员及从事新能源并网、电力系统规划等相关工作的工程师。; 使用场景及目标:①掌握蒙特卡洛方法在新能源出力模拟中的应用;②学习如何利用Matlab实现风光出力的概率建模与场景生成;③为后续研究如含高比例新能源的电力系统优化调度、风险评估等提供基础数据和技术支撑。; 阅读建议:建议读者结合文中提供的Matlab代码,逐步调试运行,重点关注随机数生成、概率分布拟合及场景削减等核心模块的实现细节,同时可尝试替换不同的风速或光照历史数据,以加深对模型泛化能力和局限性的理解。
高校技术转移办公室人员如何快速完成科技成果评价与推介书制作?.docx
高校技术转移办公室人员如何快速完成科技成果评价与推介书制作?
科技中介服务机构如何利用平台实现服务流程的智能化与轻量化?.docx
科技中介服务机构如何利用平台实现服务流程的智能化与轻量化?
科技中介服务机构如何利用平台实现技术交易的全流程数字化管理?.docx
科技中介服务机构如何利用平台实现技术交易的全流程数字化管理?
轻量级零信任邮箱验证码认证网关,项目地址https://github.com/fanstone-arch/email-auth-proxy
零依赖、高性能、单文件的通用反向代理身份认证网关。支持通过企业/个人邮箱验证码,对任意后端 Web 系统(如泛微 OA、NAS 控制台、Jenkins、GitLab 等)实施前置接入零信任(ZTA)安全合规拦截。 极致单文件分发:基于 Go 语言研发,摆脱了传统 OpenResty 繁琐的 Lua 依赖库、网络解析与容器束缚,一个二进制文件、零依赖环境即可在 Linux/Windows 生产环境秒级上线。 智能平滑双向续期:支持动态滑动续期窗口(Sliding Window)。当 Session 剩余寿命低于设定阈值且用户依然活跃时,系统自动无感重刷内存与浏览器 Cookie 周期。 身份级别智能动态分流:管理员固定访问路径 /auth/admin/monitor,系统基于当前合法的登录身份自动判定: -若非管理员账号(普通员工):网关自动放行,将其作为普通业务流量原封不动转发给后端真实系统,完美解决管理路径与业务路径发生命名冲突的生产隐患。 若是管理员账号:就地精准截断,渲染出全中文的图形化会话监控中心大屏。 工业级生产调优对齐:大文件上传保护:内置 MaxBodySize 过滤器(对齐 client_max_body_size 200m),防止大文件或恶意请求撑爆系统内存。 内存级缓冲复用:利用 Go 原生 sync.Pool 建立高效内存缓冲池(对齐 proxy_buffers),在大附件上传下载、多数据流高并发下保持极低的 GC 抖动。 安全指纹擦除:中间件强行抹除或修改 Go 的默认 Server


工具平台和程序库

