본문 바로가기

C++

스레드에 안전한 localtime()

[1. 개요]

localtime() 함수는

unix timestamp 에 대해서, 연/월/일 시간/분/초/밀리초 단위로 구할 수 있다.

 

그러나, 리턴 값에 대해서 리소스를 해제하는 코드가 없기에 내부적인 정적 버퍼의 주소를 리턴 하는 듯 한데,

실제로 그러하다.

 

따라서 이 함수는 스레드에 안전하지 않다.

스레드에 안전한 함수는 플랫폼 별로 아래와 같다.

  • Linux 계열 : localtime_r()
  • Windows 계열: localtime_s()

[2. localtime_r 예제]

#include <ctime>
#include <iostream>

int main()
{
    const std::time_t ntime = std::time(nullptr);
    const struct tm * tm0 = localtime(&ntime);

    std::cout << tm0->tm_hour << ":" << tm0->tm_min << std::endl;

    struct tm tm1;
    const struct tm * tm2 = localtime_r(&ntime, &tm1); 
    if (tm2 == nullptr) {
        std::cout << "localtime_r() fail" << std::endl;
    }
    else {
        // tm2 의 주소 값은 tm1 의 주소 값과 같다.
        std::cout << tm1.tm_hour << ":" << tm1.tm_min << std::endl;
    }

    return 0;
}

[3. localtime_s 예제]

#include <ctime>
#include <iostream>

int main()
{
    const std::time_t ntime = std::time(nullptr);
    const struct tm * tm0 = localtime(&ntime);

    std::cout << tm0->tm_hour << ":" << tm0->tm_min << std::endl;

    struct tm tm1;
    const errno_t err = localtime_s(&tm1, &ntime); 
    if (err != 0) {
        std::cout << "localtime_s() fail" << std::endl;
        std::cout << "errno: " << err << std::endl;
    }
    else {
        std::cout << tm1.tm_hour << ":" << tm1.tm_min << std::endl;
    }

    return 0;
}

'C++' 카테고리의 다른 글

함수의 중복 정의 방지  (0) 2025.09.09
버퍼에 안전한 문자열 함수  (0) 2025.09.09
segmentation fault 사례 6  (0) 2025.08.22
fsanitize 컴파일 옵션  (2) 2025.07.02
buffer overflow 사례1  (0) 2025.06.26