Может ли программа C / C ++ вызвать ошибку при чтении после конца массива (UNIX)? - PullRequest
8 голосов
/ 31 августа 2011

Я знаю, что вы можете читать после конца массива - мне интересно, если вы можете seg-fault, просто выполнив эту операцию чтения.

int someints[100];
std::cerr << someints[100] << std::endl; //This is 1 past the end of the array.

Может ли вторая строка на самом деле вызвать ошибку сегмента или она просто напечатает неровность? Кроме того, если я изменил эту память, может ли это вызвать ошибку сегмента в этой конкретной строке , или ошибка возникнет только позже, когда кто-то еще попытается использовать эту случайно измененную память?

Ответы [ 3 ]

10 голосов
/ 31 августа 2011

Это неопределенное поведение и полностью зависит от структуры виртуальной памяти, которую операционная система организовала для этого процесса. Как правило, вы можете:

  • получить доступ к некоторому бреду, который принадлежит вашему виртуальному адресному пространству, но имеет бессмысленное значение, или
  • попытка получить доступ к ограниченному адресу памяти, и в этом случае аппаратное обеспечение отображения памяти вызывает сбой страницы, и ОС решает, шлепать ли ваш процесс или выделить больше памяти.

Если someints является массивом в стеке и является последней объявленной переменной, вы, скорее всего, получите некоторую тарабарщину от вершины стека или (очень маловероятно) вызовите ошибку страницы, которая может позволить ОС изменить размер стек или убить ваш процесс с SIGSEGV.

Представьте, что вы объявляете один int сразу после массива:

int someints[100];
int on_top_of_stack = 42;
std::cerr << someints[100] << std::endl;

Тогда, скорее всего, программа должна вывести 42, если только компилятор каким-то образом не переставит порядок объявлений в стеке.

4 голосов
/ 31 августа 2011

Да, это может вызвать сбой, если память по этому адресу не доступна программе.В вашем случае это маловероятно, поскольку массив размещается в стеке и имеет длину всего 100 байт, а размер стека значительно больше (т.е. 8 МБ на поток в Linux 2.4.X), поэтому будут неинициализированные данные.Но в некоторых случаях это может привести к сбою.В любом случае этот код ошибочен, и профилировщики, такие как Valgrind, должны помочь вам устранить его.

2 голосов
/ 31 августа 2011

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

Это магия неопределенного поведения .

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