Странное поведение от ссылок в выходном потоке

Я заметил странное поведение при печати вывода в поток. Мой код перебирает большой набор данных и, среди прочего, считывает метку времени из каждого элемента. Временная метка первого элемента сохраняется, чтобы можно было рассчитать прошедшее время.

CurTime = ev[i].MidasTimeStamp;
RunTimeElapsed = difftime(CurTime,StartTime);
cout << "StartTime: " << ctime(&StartTime) << "CurTime: " << ctime(&CurTime) << "Elapsed: " << RunTimeElapsed << " s" << endl;  

Вывод, напечатанный на экране, показывает одно и то же время, напечатанное дважды, например:

StartTime: Mon Sep 23 14:44:57 2013
CurTime: Mon Sep 23 14:44:57 2013
Elapsed: 360 s

Но если разделить строку печати на две:

cout << "StartTime: " << ctime(&StartTime); 
cout << "CurTime: " << ctime(&CurTime) << "Elapsed: " << RunTimeElapsed << " s" << endl; 

Я получаю ожидаемый результат:

StartTime: Mon Sep 23 14:44:57 2013
CurTime: Mon Sep 23 14:50:57 2013
Elapsed: 360 s

Единственным изменением между двумя выходами была линия(и) cout. Это достаточно легко обойти, но я хотел бы понять, что происходит.


person Carl    schedule 17.10.2013    source источник


Ответы (1)


Из документации на ctime:

Возвращаемое значение указывает на внутренний массив, допустимость или значение которого могут быть изменены любым последующим вызовом asctime или ctime.

Порядок вычисления подвыражений в выражении не указан. В частности, компилятору разрешено сначала вызывать ctime дважды, а затем при необходимости вызывать operator<<. Это то, что, кажется, происходит в вашем случае.

person Igor Tandetnik    schedule 17.10.2013
comment
Большое спасибо, я действительно почесал голову над этим. Извините, я пропустил это в документации. - person Carl; 18.10.2013
comment
@Carl Так как именно вы подумали, что утечка памяти, вызванная ctime(), возвращающим указатель, заполнена, когда вы сами не вызываете free()? - person Oswald; 18.10.2013
comment
@oswald Какой неприятный способ ответить! Я думаю, что из моего первоначального вопроса ясно, что значение ctime(), возвращающего указатель, ускользнуло от меня. К счастью, кто-то еще дал полезный ответ. - person Carl; 18.10.2013
comment
@Carl Прости меня за мой, казалось бы, неприятный способ ответить. Я просто хотел указать, что всякий раз, когда указатель возвращается из функции, вы должны быть особенно осторожны в отношении того, кто отвечает за освобождение этой памяти. - person Oswald; 18.10.2013