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

221

Насколько опасен доступ к массиву за его пределами (в C)? Иногда может случиться, что я читаю извне массива (теперь я понимаю, что затем я получаю доступ к памяти, используемой некоторыми другими частями моей программы или даже за ее пределами), или я пытаюсь установить значение для индекса вне массива. Программа иногда вылетает, но иногда просто запускается, только давая неожиданные результаты.

Теперь я хотел бы знать, насколько это опасно на самом деле? Если это повредит моей программе, это не так плохо. Если, с другой стороны, это что-то нарушает вне моей программы, потому что мне каким-то образом удалось получить доступ к какой-то совершенно не связанной памяти, то я думаю, что это очень плохо. Я читал много «что-нибудь может случиться», «сегментация может быть наименее плохой проблемой» , «ваш жесткий диск может стать розовым, а единороги могут петь под вашим окном», что все хорошо, но в чем на самом деле опасность?

Мои вопросы:

  1. Может ли чтение значений вне массива повредить что-нибудь помимо моей программы? Я мог бы представить, что просто глядя на вещи ничего не изменится, или это, например, изменит атрибут «последний раз открыт» файла, к которому я попал?
  2. Может ли установка значений вне массива повредить что-нибудь помимо моей программы? Из этого вопроса переполнения стека я понял, что есть возможность доступа к любой ячейке памяти, что нет гарантии безопасности.
  3. Теперь я запускаю свои маленькие программы из XCode. Обеспечивает ли это дополнительную защиту моей программы, когда она не может выйти за пределы собственной памяти? Может ли это повредить XCode?
  4. Любые рекомендации о том, как безопасно выполнить мой по своей сути глючный код?

Я использую OSX 10.7, Xcode 4.6.

ChrisD
источник
В общем, ОС защитит себя и другие процессы от ваших злоумышленных действий. Это не то, на что вы обязательно хотите сильно полагаться.
Hot Licks
7
Кроме того, вы никогда не «достигнете» файла на вашем жестком диске при доступе и индексировании массива за пределами (в вашем ОЗУ).
DrummerB
1
Я полагаю, вы спрашиваете о массиве C, верно? так что это не имеет ничего общего с ObjC и не имеет отношения к какой-либо IDE.
Брайан Чен
17
Вот мой любимый пример странных результатов (это касается стека, но я нашел его действительно поучительным ...).
phipsgabler
11
xkcd.com/371
Дэн

Ответы:

125

Что касается стандарта ISO C (официальное определение языка), доступ к массиву за его пределами имеет « неопределенное поведение ». Прямое значение этого:

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

Ненормативная записка распространяется на это:

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

Такова теория. Какова реальность?

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

Это предполагает, что ваша программа работает в операционной системе, которая пытается защитить одновременно запущенные процессы друг от друга. Если ваш код работает на «голом железе», скажем, если он является частью ядра ОС или встроенной системы, то такой защиты нет; Ваш неправильный код - это то, что должно было обеспечить такую ​​защиту. В этом случае возможности повреждения значительно выше, включая, в некоторых случаях, физический ущерб оборудованию (или вещам или людям поблизости).

Даже в защищенной среде ОС защита не всегда на 100%. Например, существуют ошибки операционной системы, которые позволяют непривилегированным программам получать root (административный) доступ. Даже с обычными пользовательскими привилегиями неисправная программа может потреблять чрезмерные ресурсы (ЦП, память, диск), что может привести к выходу из строя всей системы. Многие вредоносные программы (вирусы и т. Д.) Используют переполнения буфера для получения несанкционированного доступа к системе.

(Один исторический пример: я слышал, что на некоторых старых системах с памятью ядра , многократный доступ к одной области памяти в замкнутом цикле может буквально вызвать расплавление этого фрагмента памяти. Другие возможности включают в себя разрушение дисплея CRT и перемещение чтения / записать головку дисковода с частотой гармоник шкафа привода, заставляя его ходить по столу и падать на пол.)

И всегда есть о чем беспокоиться Скайнет .

Суть заключается в следующем: если вы могли бы написать программу, чтобы сделать что-то плохое намеренно , то, по крайней мере, теоретически возможно, что ошибочная программа могла бы сделать то же самое случайно .

На практике очень маловероятно, что ваша глючная программа, работающая в системе MacOS X, сделает что-то более серьезное, чем сбой. Но невозможно полностью предотвратить ошибочный код от действительно плохих действий.

Кит Томпсон
источник
1
спасибо, я на самом деле полностью понимаю это. Но это сразу же вызывает дополнительный вопрос: что может сделать начинающий программист, чтобы защитить свой компьютер от его / ее собственных, возможно, ужасных творений? После того, как я тщательно проверил программу, я могу использовать ее в мире. Но первый пробный запуск должен быть неправильной программой. Как вы, ребята, защищаете свои системы от себя?
ChrisD
6
@ChrisD: мы, как правило, везет. 8-)} Серьезно, защита на уровне ОС довольно хороша в наши дни. В худшем случае, если я напишу случайную вилочную бомбу , мне, возможно, придется перезагрузиться, чтобы восстановиться. Но реальный ущерб системе, вероятно, не стоит беспокоить, если ваша программа не пытается что-то сделать на грани опасности. Если вы действительно беспокоитесь, запуск программы на виртуальной машине может быть неплохой идеей.
Кит Томпсон,
1
С другой стороны, я видел много странных вещей, происходящих на компьютерах, которые я использовал (поврежденные файлы, неустранимые системные ошибки и т. Д.), И я не представляю, сколько из них могло быть вызвано тем, что некоторые программы на С демонстрировали страшное неопределенное поведение. (Пока что из моего носа не вылетели настоящие демоны.)
Кит Томпсон,
1
спасибо за то, что
научили меня разламывать
2
Scientificamerican.com/article/… так что огонь все еще возможен с современной электроникой.
Mooing Duck
25

В целом, современные операционные системы (в любом случае, популярные) запускают все приложения в защищенных областях памяти с помощью диспетчера виртуальной памяти. Оказывается, это не очень ЛЕГКО (если можно так выразиться) просто читать или записывать в местоположение, которое существует в РЕАЛЬНОМ пространстве за пределами региона (-ов), которые были назначены / выделены вашему процессу.

Прямые ответы:

1) Чтение почти никогда не повредит непосредственно другому процессу, однако может косвенно повредить процесс, если вам случится прочитать значение KEY, используемое для шифрования, дешифрования или проверки программы / процесса. Чтение за пределами может иметь несколько неблагоприятных / неожиданных последствий для вашего кода, если вы принимаете решения на основе данных, которые вы читаете

2) Единственный способ, которым вы могли бы действительно повредить что-либо, записав в локатор, доступный по адресу памяти, - это если адрес памяти, в который вы пишете, на самом деле является аппаратным регистром (местоположение, которое на самом деле не для хранения данных, а для управления какой-то частью аппаратного обеспечения) не место в оперативной памяти. На самом деле, вы все равно обычно не повредите что-либо, если не пишете какое-то одноразовое программируемое место, которое нельзя перезаписать (или что-то в этом роде).

3) Как правило, запуск из отладчика запускает код в режиме отладки. Работа в режиме отладки позволяет TEND (но не всегда) останавливать ваш код быстрее, когда вы сделали что-то, что считается непрактичным или совершенно незаконным.

4) Никогда не используйте макросы, используйте структуры данных, в которые уже встроена проверка границ индекса массива и т. Д ....

ДОПОЛНИТЕЛЬНО Я должен добавить, что приведенная выше информация действительно только для систем, использующих операционную систему с окнами защиты памяти. Если вы пишете код для встроенной системы или даже системы, использующей операционную систему (в режиме реального времени или другую), у которой нет окон защиты памяти (или окон с виртуальной адресацией), следует соблюдать большую осторожность при чтении и записи в память. Также в этих случаях всегда следует применять методы кодирования SAFE и SECURE, чтобы избежать проблем с безопасностью.

trumpetlicks
источник
4
Безопасные и надежные методы кодирования всегда должны применяться.
Ник Бугалис
3
Я бы посоветовал НЕ использовать try / catch для глючного кода, если вы не ловите очень специфические исключения и не знаете, как их исправить. Catch (...) - это худшая вещь, которую вы можете добавить в код ошибки.
Евгений
1
@NikBougalis - я полностью согласен, но ДАЖЕ БОЛЬШЕ ВАЖНО, если в ОС нет защиты памяти / виртуальных адресных пространств или не хватает ОС :-)
trumpetlicks
@ Евгений - я никогда не замечал, что это будет проблемой для меня, но я согласен с вами, я отредактировал это :-)
trumpetlicks
1) Вы имеете в виду ущерб, потому что я бы раскрыл что-то, что должно было остаться в секрете? 2) Я не уверен, что понял, что вы имеете в виду, но я полагаю, что я получаю доступ только к ОЗУ, пытаясь получить доступ к местоположениям за пределами границ массива?
ChrisD
9

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

Это означает, что ваш пользователь может отправить вам строку, которая будет вызывать вашу программу по сути exec("/bin/sh"), которая превратит ее в оболочку, выполняя все, что он хочет в вашей системе, включая сбор всех ваших данных и превращение вашей машины в узел бот-сети.

Смотрите Smashing The Stack для удовольствия и прибыли, чтобы узнать, как это можно сделать.

че
источник
Я знаю, что не должен обращаться к элементам массива за пределами границ, спасибо за усиление этой точки. Но вопрос в том, что, помимо причинения всякого вреда моей программе, могу ли я случайно выйти за пределы памяти моей программы? И я имею в виду OSX.
ChrisD
@ChrisD: OS X - современная операционная система, поэтому она обеспечит вам полную защиту памяти. Например, вы не должны ограничиваться тем, что разрешено делать вашей программе. Сюда не следует связываться с другими процессами (если только вы не работаете с правами root).
Че
Я бы предпочел сказать под привилегией 0, а не root.
Руслан
Более интересным является то , что гипер-современный компилятор может принять решение о том , что если код пытается читать foo[0]через foo[len-1]после того , как ранее использовал проверку в lenотношении длины массива либо выполнить или пропустить фрагмент кода, компилятор должен чувствовать себя свободно работать , что другой код безоговорочно даже если бы приложение владело хранилищем после массива и эффектами чтения, он был бы доброкачественным, но эффект вызова другого кода не был бы.
суперкат
8

Ты пишешь:

Я читал много «все может случиться», «сегментация может быть наименее плохой проблемой», «твой жесткий диск может стать розовым, а единороги могут петь под твоим окном», что все хорошо, но в чем на самом деле опасность?

Скажем так: зарядите пистолет. Направьте его за окно без особой цели и огня. В чем опасность?

Проблема в том, что вы не знаете. Если ваш код перезаписывает что-то, что приводит к сбою вашей программы, у вас все в порядке, потому что это остановит его в определенном состоянии. Однако, если это не терпит крах, тогда проблемы начинают возникать. Какие ресурсы находятся под контролем вашей программы и что она может с ними сделать? Какие ресурсы могут попасть под контроль вашей программы и что она может с ними сделать? Я знаю по крайней мере одну серьезную проблему, которая была вызвана таким переполнением. Проблема заключалась в, казалось бы, бессмысленной статистической функции, которая испортила некоторую несвязанную таблицу преобразования для производственной базы данных. Результатом была некоторая очень дорогая очистка впоследствии. На самом деле, было бы намного дешевле и проще справиться, если бы эта проблема отформатировала жесткие диски ... другими словами: розовые единороги могут быть вашей наименьшей проблемой.

Идея о том, что ваша операционная система защитит вас, оптимистична. Если возможно, постарайтесь не писать за пределами.

Удо Кляйн
источник
хорошо, это было именно то, чего я боялся. Я постараюсь не писать без границ », но, видя то, что я делал последние несколько месяцев, я, безусловно, буду делать это еще много. Как вы, ребята, так хорошо научились программировать без безопасного способа тренировки?
ChrisD
3
Кто сказал, что все когда-либо было безопасно;)
Удо Кляйн
7

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

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

Если вы попытаетесь получить доступ к любой памяти, не выделенной вашему процессу, операционная система остановит выполнение вашей программы с ошибкой сегментации.

Таким образом, напрямую (без запуска от имени root и прямого доступа к файлам, таким как / dev / mem) нет никакой опасности, что ваша программа будет мешать любой другой программе, работающей в вашей операционной системе.

Тем не менее - и, вероятно, это то, о чем вы слышали с точки зрения опасности, - слепая случайная запись случайных данных в случайные места памяти случайно приводит к тому, что вы можете повредить все, что сможете.

Например, ваша программа может захотеть удалить определенный файл, заданный именем файла, хранящимся где-то в вашей программе. Если случайно вы просто перезаписали место, где хранится имя файла, вы можете удалить совершенно другой файл.

mikyra
источник
1
Если будут запущены как корень (или каким - либо другим привилегированным пользователь), хотя, берегитесь. Переполнение буфера и массива - это обычная вредоносная программа.
Джон Боде
фактически учетная запись, которую я использую для всех своих ежедневных вычислений, не является учетной записью администратора (я использую терминологию OSX, поскольку это моя система). Вы хотите сказать мне, что я не могу повредить что-либо, пытаясь установить ЛЮБУЮ область памяти? Это на самом деле отличные новости!
ChrisD
Как уже упоминалось ранее, худший вред, который вы можете нанести случайно, - это худший вред, который вы можете нанести как пользователь. Если вы хотите быть на 100% уверены, что не уничтожите свои данные, возможно, вы захотите добавить другую учетную запись на свой компьютер и поэкспериментировать с этим.
Микира
1
@mikyra: Это верно, только если защитные механизмы системы эффективны на 100%. Наличие вредоносного ПО говорит о том, что на это нельзя всегда полагаться. (Я не хочу предполагать, что об этом обязательно стоит беспокоиться; возможно, но маловероятно, что программа может случайно использовать те же дыры в безопасности, которые используются вредоносными программами.)
Кит Томпсон,
1
Список здесь включает: Запуск кода из ненадежных источников. Просто нажмите кнопку «ОК» в любом всплывающем окне брандмауэра, даже не читая о чем идет речь, или полностью отключите его, если не удается установить нужное сетевое соединение. Исправление бинарных файлов с помощью новейшего хака из сомнительных источников. Это не вина хранилища, если владелец добровольно пригласит любого грабителя с широко открытыми руками и очень крепкими укрепленными дверями.
Микира
4

NSArrayS в Objective-C назначается определенный блок памяти. Превышение границ массива означает, что вы будете обращаться к памяти, которая не назначена массиву. Это означает:

  1. Эта память может иметь любое значение. Там нет никакого способа узнать, являются ли данные действительными на основе вашего типа данных.
  2. Эта память может содержать конфиденциальную информацию, такую ​​как личные ключи или другие учетные данные пользователя.
  3. Адрес памяти может быть недействительным или защищенным.
  4. Память может иметь изменяющееся значение, потому что к ней обращается другая программа или поток.
  5. Другие вещи используют адресное пространство памяти, например отображаемые в память порты.
  6. Запись данных на неизвестный адрес памяти может привести к сбою вашей программы, перезаписи пространства памяти ОС и, как правило, к взрыву солнца.

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

Ричард Браун
источник
NSArraysесть за пределами исключения. И этот вопрос, кажется, о массиве C.
Барабанщик
Я действительно имел в виду C-массивы. Я знаю, что есть NSArray, но сейчас большинство моих упражнений - на C
ChrisD
4

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

Из руководства:

Memcheck - это детектор ошибок памяти. Он может обнаружить следующие проблемы, которые часто встречаются в программах на C и C ++.

  • Получать доступ к памяти не следует, например, переполнение и недогрузку блоков кучи, переполнение вершины стека и доступ к памяти после ее освобождения.
  • Использование неопределенных значений, то есть значений, которые не были инициализированы или были получены из других неопределенных значений.
  • Неправильное освобождение памяти кучи, например, двойное освобождение блоков кучи, или несоответствующее использование malloc / new / new [] по сравнению с free / delete / delete []
  • Перекрывающиеся указатели src и dst в memcpy и связанных функциях.
  • Утечки памяти.

ETA: Хотя, как говорится в ответе Kaz, это не панацея и не всегда дает наиболее полезные результаты, особенно когда вы используете захватывающие шаблоны доступа.

Aesin
источник
Я подозреваю, что Анализатор XCode найдет большую часть этого? и мой вопрос не столько в том, как найти эти ошибки, но если выполнение программы, у которой все еще есть эти ошибки, опасно для памяти, не выделенной для моей программы. Мне нужно будет выполнить программу, чтобы увидеть, как происходят ошибки
ChrisD
3

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

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

В некоторых случаях аппаратное обеспечение будет переносить адреса (наиболее значимые биты / байты адреса игнорируются), поэтому запись по адресу, выходящему за пределы физического адресного пространства, фактически приведет к записи данных прямо в середине.

И, наконец, старые процессоры, такие как MC68000, могут быть заблокированы до такой степени, что только аппаратный сброс может привести их в действие. Я не работал над ними пару десятилетий, но я полагаю, что когда он столкнулся с ошибкой шины (несуществующей памятью) при попытке обработать исключение, он просто остановился бы до тех пор, пока не был произведен аппаратный сброс.

Моя самая большая рекомендация - откровенный штекер для продукта, но я не заинтересован в нем, и я никоим образом не связан с ним - но основан на паре десятилетий программирования на C и встроенных системах, где надежность была критической, ПК Gimpel Lint не только обнаружит подобные ошибки, но и сделает из вас лучшего программиста на C / C ++, постоянно обращая внимание на вредные привычки.

Я также рекомендую прочитать стандарт кодирования MISRA C, если вы можете получить копию от кого-то. Я не видел ни одного недавнего из них, но в старые времена они давали хорошее объяснение того, почему вы не должны / не должны делать то, что они освещают.

Не знаю о вас, но примерно во 2-й или 3-й раз, когда я получаю coredump или зависание из любого приложения, мое мнение о том, какая компания его произвела, снижается вдвое. В 4-й или 5-й раз и независимо от того, какая упаковка находится, она становится полкой, и я вбиваю деревянную колу через центр упаковки / диска, в который она попала, просто чтобы убедиться, что она никогда не вернется, чтобы преследовать меня.

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

Я работаю с компилятором для чипа DSP, который намеренно генерирует код, который обращается к концу массива из кода C, который не имеет!

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

Подобный код на C вызывает неопределенное поведение, но это лишь формальность из документа стандартов, который касается максимальной переносимости.

Чаще всего это не так, программа, которая выходит за границы, не умно оптимизирована. Это просто глючит. Код извлекает некоторое мусорное значение и, в отличие от оптимизированных циклов вышеупомянутого компилятора, код затем использует значение в последующих вычислениях, тем самым разрушая их.

Стоит обнаруживать подобные ошибки, и поэтому стоит сделать поведение неопределенным даже по одной этой причине: во время выполнения может появиться диагностическое сообщение типа «переполнение массива в строке 42 файла main.c».

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

Кроме того, обратите внимание, что в C нам разрешено создавать указатель, который находится за концом массива. И этот указатель должен сравнивать больше любого указателя на внутреннюю часть массива. Это означает, что реализация C не может поместить массив прямо в конец памяти, где адрес «один плюс» будет оборачиваться и выглядеть меньше, чем другие адреса в массиве.

Тем не менее, доступ к неинициализированным или выходящим за пределы значениям иногда является допустимым методом оптимизации, даже если он не является максимально переносимым. Именно поэтому инструмент Valgrind не сообщает о доступе к неинициализированным данным, когда такой доступ происходит, а только тогда, когда значение впоследствии используется каким-либо образом, что может повлиять на результат программы. Вы получаете диагностику типа «условная ветвь в xxx: nnn зависит от неинициализированного значения», и иногда бывает трудно отследить, где оно происходит. Если бы все такие обращения были немедленно зафиксированы, было бы много ложных срабатываний, возникающих из оптимизированного компилятором кода, а также из правильно оптимизированного вручную кода.

Говоря об этом, я работал с некоторым кодеком от поставщика, который выдавал эти ошибки при портировании на Linux и запуске под Valgrind. Но продавец убедил меня, что только несколько битиспользуемого значения на самом деле происходило из неинициализированной памяти, и эти биты тщательно избегались логикой. Использовались только хорошие биты значения, и Valgrind не может отследить отдельный бит. Неинициализированный материал был получен при чтении слова после конца потока битов закодированных данных, но код знает, сколько битов находится в потоке, и не будет использовать больше битов, чем есть на самом деле. Поскольку доступ за концом массива битового потока не наносит вреда архитектуре DSP (после массива нет виртуальной памяти, нет портов с отображением в памяти и адрес не переносится), это допустимый метод оптимизации.

«Неопределенное поведение» на самом деле ничего не значит, потому что согласно ISO C простое включение заголовка, который не определен в стандарте C, или вызов функции, которая не определена в самой программе или стандарте C, являются примерами неопределенного поведение. Неопределенное поведение не означает «не определено никем на планете», просто «не определено стандартом ISO C». Но, конечно же , иногда неопределенное поведение действительно является абсолютно не определен никем.

Kaz
источник
Кроме того, при условии, что существует, по крайней мере, одна программа, которую конкретная реализация обрабатывает правильно, даже если она номинально облагает налогом все ограничения реализации, указанные в Стандарте, эта реализация может вести себя произвольно при подаче любой другой программы, которая свободна от нарушений ограничений и все еще будет " совместимый». Следовательно, 99,999% программ на C (что угодно, кроме «единой программы» платформы) полагаются на поведение, при котором Стандарт не предъявляет никаких требований.
суперкат
1

Кроме вашей собственной программы, я не думаю, что вы что-то сломаете, в худшем случае вы попытаетесь прочитать или записать адрес памяти, который соответствует странице, которую ядро ​​не назначило вашим процессам, сгенерировав соответствующее исключение и быть убитым (я имею в виду, ваш процесс).

jbgs
источник
3
..Какой? Как насчет перезаписи памяти в вашем собственном процессе, который использовался для хранения некоторой переменной, использованной позже ... которая теперь таинственным образом изменила свое значение! Уверяю вас, эти ошибки очень интересны. Segfault будет лучшим результатом. -1
Эд С.
2
Я имею в виду, что он не будет "нарушать" другие процессы, кроме своей собственной программы;)
jbgs
Мне действительно все равно, если я нарушу свою собственную программу. Я только учусь, программа в любом случае явно ошибается, если я получаю доступ к чему-либо вне моего массива. Я просто все больше и больше беспокоюсь о рисках, которые могут сломать что-то еще при отладке моих творений
ChrisD
Дело в том, могу ли я быть уверенным, что если я попытаюсь получить доступ к памяти, которая мне не назначена, мой процесс будет убит? (будучи на OSX)
ChrisD
3
Несколько лет назад я был неуклюжим программистом на Си. Я обращался к массивам за их пределами сотни раз. Кроме того, что мой процесс был убит операционной системой, ничего не произошло.
JBGS