Вопрос:

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

c++ c unix

831 просмотра

3 ответа

21027 Репутация автора

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

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

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

Автор: John Humphreys - w00te Источник Размещён: 31.08.2011 05:38

Ответы (3)


10 плюса

35694 Репутация автора

Решение

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

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

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

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

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

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

Автор: Blagovest Buyukliev Размещён: 31.08.2011 05:43

4 плюса

0 Репутация автора

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

Автор: user405725 Размещён: 31.08.2011 05:43

2 плюса

183357 Репутация автора

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

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

Автор: Carl Norum Размещён: 31.08.2011 05:44
Вопросы из категории :
32x32