Ошибка при передаче `time_t` и `struct tm`, ESP32
Мне нужно создать преобразователь времени эпохи, хранящегося в переменной time_t
, в переменную struct tm
, чтобы проверять/создавать определенную задачу каждый час или день. Эта функция также должна получить прошлое time_t
для других целей.
Функция преобразования внутри библиотеки работает нормально (последние две строки предназначены для проверки, то есть преобразование было выполнено, как ожидалось):
void myIOT32::convEpoch(time_t in_time, struct tm *convTime)
{
convTime = gmtime(&in_time);
char time_char[40];
sprintf(time_char, "%04d-%02d-%02d %02d:%02d:%02d", convTime->tm_year + 1900, convTime->tm_mon+1, convTime->tm_mday,
convTime->tm_hour, convTime->tm_min, convTime->tm_sec);
Serial.print(" from funct: ");
Serial.println(time_char);
Теперь, когда я вызываю его из моего кода и пытаюсь использовать переменную time tm
, это приводит к сбою кода. В приведенном ниже коде я просто пытаюсь вывести его на консоль:
void sendnewNotif()
{
struct tm *newtime;
time_t t=182423032;
iot.convEpoch(t, newtime); // <--- Использование преобразования
char timeStamp[50];
// Serial.print(newtime->tm_year);
}
В чем может быть проблема?
Парень
@Guy . D, 👍0
Обсуждение1 ответ
Лучший ответ:
void myIOT32::convEpoch(time_t in_time, struct tm *convTime)
{
convTime = gmtime(&in_time);
Здесь вы перезаписываете параметр convTime
. Нет смысла в
передавая такой параметр, если вы не собираетесь использовать предоставленное значение.
void sendnewNotif()
{
struct tm *newtime;
time_t t=182423032;
iot.convEpoch(t, newtime); // <--- Использование преобразования
newtime
изначально не инициализирован. Вызов iot.convEpoch()
это не меняет (параметр передается по значению, а не по
ссылка).
Serial.print(newtime->tm_year);
Это разыменование неинициализированного указателя, который не определен. поведения и может привести к сбою программы.
Самое простое решение, которое я вижу, — заставить myIOT32::convEpoch()
возвращать
указатель, полученный от gmtime()
. Обратите внимание, что это указывает на статическое хранилище,
что делает метод нереентерабельным.
Пример (не проверено):
struct tm *myIOT32::convEpoch(time_t in_time)
{
struct tm *convTime = gmtime(&in_time);
// ...
return convTime;
}
void sendnewNotif()
{
time_t t = 182423032;
struct tm *newtime = iot.convEpoch(t);
Serial.print(newtime->tm_year);
}
спасибо за ваш добрый и исчерпывающий ответ :), но ваш ответ еще больше поднялся: а) какое это имеет значение, если он инициализирован? так как он получает свое значение позже (хотя и как указатель). б) есть ли указания, когда использовать в качестве возвращаемого значения (как вы только что предложили) или, как я сделал, передавая его значение/ссылку (в случае, если он работает так, как ожидалось...) ?, @Guy . D
а) Он не получает свое значение позже. б) В принципе, вы могли бы передать указатель по ссылке, но смешивание указателей и ссылок может быстро привести к путанице., @Edgar Bonet
- Документация ESP32 для "time.h"
- ESP32 секунды от эпохи
- Установить время настенных часов или изменить смещение GMT без ntp-сервера?
- Как установить RTC в ES32 с помощью NTP-сервера?
- Обратная связь ESP32 от NTP
- (Почему) успешное завершение getLocalTime() на ESP32 занимает несколько секунд
- Не удалось преобразовать time_T из прошлого в структуру tm
- Размер структуры tm (datetime) отличается в ESP32 от linux64x
struct tm newtime;
для размещения в стеке.struct tm *newtime
— указатель в никуда, @Juraj