Свободная функция на самом деле не освобождает память от C [duplicate]

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

Предположим, что существует пакет A

  A / \ file1.java file2.java  

file1.java

  package A;  class file1 {public static void main (String args []) {}} public class file3 {public static void main (String args []) {}}  

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

Предположим, что пакет A содержит только файлы Java (без файлов классов), а некоторый класс вне пакета A пытается получить доступ к файлу с открытым классом3, компилятор сначала попытается найти file3.class (недоступно ), тогда он попытается найти file3.java (недоступно). Таким образом, хотя класс file3 носит публичный характер, он не виден во внешнем мире. Поэтому, если компилятор устанавливает ограничение на то, что если файл содержит открытый класс, его следует назвать таким же, как имя открытого класса, тогда проблема выше может быть решена, и разработчику не придется думать об экспонировании открытого класса во внешний мир .

Компилятор также устанавливает ограничение на то, что в каждом Java-файле должен быть один открытый класс, так что к любому публичному классу может быть доступен внешний мир.

4
задан Yuri 15 March 2013 в 14:10
поделиться

5 ответов

Поскольку использование недопустимого указателя вызывает неопределенное поведение. И это означает, что поведение ... хорошо ... undefined. Это не обязано сбой.

18
ответ дан user 16 August 2018 в 05:20
поделиться
  • 1
    В сборках Debug в VS runtime обычно перезаписывает память с чем-то недействительным, поэтому легче обнаружить ошибки. Тем не менее, он не делает этого в релизе. – sashoalm 16 February 2018 в 10:12

Почему курица может продолжать бегать и прыгать, несмотря на то, что ее голову отрубают? Обратите внимание, что это не всегда всегда ; некоторые цыплята могут перестать двигаться немедленно, а другие могут продолжать работать в течение нескольких месяцев . Когда это происходит, это происходит, потому что это происходит. Означает ли это, что мы должны вырезать наши домашние животные?

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

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

2
ответ дан autistic 16 August 2018 в 05:20
поделиться

Когда вы вызываете free(phead), память phead указывает на освобождение, но значение phead остается нетронутым, делая указатель phead a болтающимся . Доступ к освобожденной памяти создает неопределенное поведение.

Хорошей практикой является назначение указателя NULL указателю, когда вы освободите память, на которую он указывает:

free(phead);
phead = NULL;
9
ответ дан LihO 16 August 2018 в 05:20
поделиться
  • 1
    присвоение NULL ... не поможет всегда, так что это скорее неясность, которая может затенять еще одну ошибку. (head = malloc (); list = head; free (head); head = NULL; = & gt; список все еще указывает на свободную память) – Peter Miehle 15 March 2013 в 14:31
  • 2
    @PeterMiehle: Я не говорю, что назначение указателя NULL указателю решит все проблемы в мире, и все программисты будут счастливы когда-либо. Я просто говорю, что это хорошая практика, как избежать создания дополнительных висячих указателей. – LihO 15 March 2013 в 14:37
  • 3
    @PeterMiehle Что? Если вы назначили NULL на head, он не будет указывать на память free() d ... – user 15 March 2013 в 14:45
  • 4
    @ H2CO3, но список будет, как я писал ... – Peter Miehle 15 March 2013 в 16:55
  • 5
    @PeterMiehle: Существуют ситуации, когда присвоение NULL после памяти free() d вполне разумно и предназначено. Иногда это не только хорошая практика, но и важная вещь. – LihO 15 March 2013 в 17:08

Поскольку память по-прежнему отображается в ваш процесс, но не выделяется. В программе C есть два уровня управления памятью: во-первых, ядро ​​дает вам страницы, на которые вы можете писать. Если для процесса требуется больше памяти, которую он отобразил, он должен запросить больше из ядра (sbrk). Это происходит в больших кусках, поэтому malloc разрезает его на куски для вас, запрашивая больше страниц по мере необходимости, но используя, где возможно, память, уже выделенную для программы. free не может вернуть страницу до тех пор, пока все используемые ею распределения не будут освобождены.

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

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

4
ответ дан Nicholas Wilson 16 August 2018 в 05:20
поделиться

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

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

4
ответ дан Ziffusion 16 August 2018 в 05:20
поделиться
  • 1
    «Память не просто исчезает, а ее содержимое не очищается». не указывается C. Он может быть очищен - он может и не быть. – chux 14 September 2017 в 02:37
Другие вопросы по тегам:

Похожие вопросы: