Возврат структуры в функции C вызывает ошибку сегментации - PullRequest
0 голосов
/ 02 октября 2018

Я задаю этот вопрос скорее из любопытства, чем из-за реальной необходимости, но это меня некоторое время сбивало с толку.Я действительно хотел бы знать, что не так с моим кодом ниже.Кстати, не пытайтесь понять цель функции - она ​​просто предназначена для того, чтобы показать проблему.

Приведенный ниже код вызывает ошибку сегментации при запуске в Linux (используя gcc), но он прекрасно работает в Windows(используя Visual Studio).Насколько я знаю, нет ничего плохого в том, чтобы возвращать структуру по значению, так что я делаю неправильно ниже?

#include <time.h>
#include <stdint.h>

using namespace std;

struct tm testFunc(const uint32_t rawtime) {
  struct tm * localTime;
  localTime = gmtime ((const time_t*)&rawtime);
  struct tm testval = *localTime;
  return testval;
}

int main() {
  uint32_t now = 1538442104;
  testFunc(now);
}

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Строка gmtime приводит к неопределенному поведению.localTime = gmtime((const time_t*)&rawtime); преобразует uint32_t* в time_t*, но нет гарантии, что размеры одинаковы, действительно, на многих современных платформах time_t составляет 64 бита.

Если это не приводит к сбою, тоgmtime, скорее всего, получает нежелательную информацию, а затем возвращает ноль, и в этот момент testval = *localtime падает при чтении из нулевого указателя.

0 голосов
/ 02 октября 2018

time_t в Linux (по крайней мере, на моем компьютере RHEL6) - это signed long, размер которого будет 64-битным при 64-битной сборке.Вы передаете адрес uint32_t, что означает, что gmtime читает четыре байта мусора, вызывая неопределенное поведение.

Windows, по-видимому, по умолчанию также 64-битная time_t, но это *У 1008 * есть возможность заставить его использовать 32-битный тип за счет возможного запуска ошибки Y2038.В любом случае, он может просто работать в Windows по совпадению (в конце концов, неопределенное поведение может включать в себя «работает как положено»).

Когда значение огромно, gmtime может в итоге вернуть NULL,которая вызовет ошибку, если вы попытаетесь прочитать ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...