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

C++程序调用mktime()持续分配堆内存占用增长问题求助

问题原因
  • 你遇到的是glibc老版本(对应你Raspbian 10/Buster系统搭载的glibc 2.28版本)的已知问题:mktime内部处理时区信息时,若未提前初始化时区数据、或传入的struct tm未完整初始化,会反复分配小体积的时区缓存块,这些块被挂在libc全局结构体上,valgrind会标记为still reachable不算直接泄漏,但长时间运行会持续占用内存。
  • 你的代码还有两个触发问题的诱因:1. 全局struct tm result没有每次使用前完整初始化,仅赋值了年月日时分秒字段,tm_isdst(夏令时标记)等字段的值不确定,会强制mktime每次调用都重新查询时区信息;2. 没有提前初始化时区,mktime每次调用都会尝试加载时区数据产生额外分配。
解决方案

方案1:快速修复(修改现有代码,无需换实现)

  • 程序启动时调用一次tzset()完成全局时区初始化,避免mktime重复加载时区。
  • 每次使用struct tm前完整初始化所有字段,尤其显式指定tm_isdst的值:如果不需要处理夏令时可以直接设为0,设为-1则让mktime自动判断。可以把全局result改成函数局部变量,每次定义时清零,避免残留值干扰。
    修改后的tmConvert_t参考代码:
unsigned long long tmConvert_t(int YY, short MM, short DD, short hh, short mm, short ss) {
    struct tm result = {0}; // 局部变量,每次初始化全0
    result.tm_sec = ss;
    result.tm_min = mm;
    result.tm_hour = hh;
    result.tm_year = YY - 1900;
    result.tm_mon = MM;
    result.tm_mday = DD;
    result.tm_isdst = -1; // 显式指定夏令时标记由mktime自动判断
    time_t converted = mktime(&result);
    return (unsigned long long)converted * 1000; 
}

程序入口加初始化逻辑:

#include <time.h>
// main函数最开始调用一次
tzset();

方案2:彻底规避(用C++ chrono接口替代libc时间函数)

既然你已经用了C++11及以上的std::chrono,完全可以不用libc的mktime/localtime系列函数,直接用chrono计算当天午夜时间戳,彻底避开libc的实现问题:

#include <chrono>
using namespace std::chrono;

void updateTime() {
    auto now = system_clock::now();
    currentMillisTime = duration_cast<milliseconds>(now.time_since_epoch()).count();
    
    // 直接用chrono算当天午夜,不需要调用mktime
    auto dayPoint = floor<days>(now);
    midnightMillis = duration_cast<milliseconds>(dayPoint.time_since_epoch()).count();
    
    // 获取年月日周日信息
    time_t t = system_clock::to_time_t(now);
    struct tm result;
    localtime_r(&t, &result);
    currentDay = result.tm_mday;
    currentMonth = result.tm_mon;
    currentYear = result.tm_year + 1900;
    currentWeekday = result.tm_wday;
}

该方案完全不会触发libc的mktime分配问题,长期运行更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:06:01