Любопытно, cout, когда на следующей строке есть ошибка шины

Мне интересно, как cout работает с ошибками шины / сегментации. У меня есть два примера ниже. Потому что я не знаю, как повторить ошибку шины, которую вы должны принять, если от меня эта сетка. DoMovement в этом примере выдает ошибку шины. Пока я что-то делал перед строкой ошибки шины, я заметил, что, если я вставлю в нее конечную строку, она распечатается нормально, но если я не вставлю в нее конец, это не так. Примеры внизу показывают, что я имею в виду.

Почему, если вы не ставите конечную линию в cout и у вас есть ошибка шины в одной из последних строк, она не выводит «пример 2»?

Пример 1:

std::cout << "example 1" << endl;
grid.DoMovement();

Выход

works
bus error

Пример 2:

std::out << "example 2";
grid.DoMovement();

Выход

bus error

2

Решение

По умолчанию IOStreams буферизируются. Все, что только записано в буфер, не будет отображаться. Когда вы используете std::endl с потоком добавляется перевод строки, а поток сбрасывается. Обратите внимание, что обычно вы не хотите сбросить поток: частая очистка потоков может значительно снизить производительность! Таким образом, это хорошая идея, чтобы не использовать std::endl но '\n' если вы хотите новую строку. Если вы действительно хотите очистить поток, вы можете явно использовать std::flush который просто промывает поток.

Во время отладки может быть полезно, чтобы весь вывод отображался сразу после его записи, чтобы сбой не помешал отображению вывода. Если вы последуете указанным выше советам и не будете часто сбрасывать, большая часть выходных данных может быть помещена в буфер. Простым средством для этого является использование std::unitbuf: этот манипулятор включает флаг std::ios_base::unitbuf заставлять выходные потоки очищаться после каждой вставки. Вы можете снова выключить флаг, используя std::nounitbuf чтобы избежать замедления в секциях кода, которые, как известно, работают (или, по крайней мере, известны как не слишком драматичные):

std::cout << std::unitbuf;   // turn on automatic flushing
problematic_code();
std::cout << std::nounitbuf; // turn off automatic flushing

Настройки по умолчанию для std::ios_base::unitbuf это разница между std::cerr а также std::clog: оба потока записывают в стандартный поток ошибок (в файловом дескрипторе 2 UNIXes), но std::cerr очищает свой буфер после каждой записи std::clog не.

4

Другие решения

std::endl не только добавляет новую строку в поток, но также очищает текущий буфер выходного потока. Если вы получите ошибку шины, когда некоторые данные находятся в буфере потока вывода, вы не увидите эти данные.

4

std::cout буферизируется, когда std::cerr не является.
Если вы тестируете с std::cerr, с или без std::endl, вы увидите ваше сообщение.

http://www.cplusplus.com/reference/iostream/manipulators/endl

1

endl «магический» манипулятор, который выводит символ новой строки и очищает буфер вывода.

Буфер также обычно очищается после завершения программы, поэтому вы обычно не можете видеть дополнительный эффект endl, Но если ваша программа вылетает вскоре после этого, буферы не очищаются и вывод не появляется.

Вы можете изменить свой второй пример на

std::out << "example 2" << flush;

чтобы увидеть эффект покраснения.

1