Разница в реализации malloc и new.Реализация стека? - PullRequest
4 голосов
/ 26 февраля 2011

При выделении памяти новый оператор выдает исключение, если память недоступна.С другой стороны, malloc возвращает NULL.В чем причина разницы в реализации.Кроме того, при статическом распределении памяти, то есть в стеке, есть ли исключение, если у нас заканчивается память?

Я уже прошел по ссылке В чем разница между new / delete и malloc /бесплатно? но не получил мой ответ о разнице в реализации двух

Ответы [ 5 ]

5 голосов
/ 26 февраля 2011

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

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

Таким образом, в C ++ возникли исключения.
Теперь, когда возникает ошибка, код не продолжается (следовательно, нет повреждения памяти), но разматывает стек (потенциальнозаставляя приложение выйти).Если вы можете решить проблему, вы должны явно добавить код для обработки ситуации, прежде чем продолжить.Таким образом, вы не можете случайно забыть не проверять состояние ошибки;либо вы проверите его, либо приложение выйдет из системы.

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

Кроме того, при статическом распределении памяти, то есть в стеке, есть ли исключение, если у нас заканчивается память?

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

Примечание

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

2 голосов
/ 26 февраля 2011

malloc не может выдать исключение, потому что это нарушит совместимость с C. new вызывает исключение, потому что это предпочтительный способ в C ++ сигнализировать об ошибках.ранние версии C ++, new действительно возвращали 0 при ошибке,

1 голос
/ 26 февраля 2011

Риск, возможно, добавит некоторую путаницу ...

  • malloc является обычной C-функцией. Поскольку это C, он может сигнализировать об ошибках только способами, подходящими для программы на C: используя возвращаемое значение, аргумент, передаваемый указателем или глобальной переменной (например, errno).
  • new вводит выражение C ++, вызывает operator new для получения памяти, а затем создает объект. Либо operator new, либо конструкторы могут выбросить.

Примечание: в выражении new нет выражения

Большинство operator new обычно реализуются в терминах malloc, но, как я заметил, выражение new - это нечто большее, чем просто получение памяти, поскольку оно также создает объект (ы).

Он также заботится об управлении, пока не выпустит его вам. То есть, если конструктор выдает, то он должным образом освобождает память, которая была выделена, и в случае выражения new[] (которое строит массив) вызывает деструктор тех объектов, которые уже были построены.

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

Обратите внимание, что gcc вводит опцию split-stack для компиляции, которая заключается в выделении минимального стека и последующем его увеличении по требованию. Это аккуратно обходит проблему возможных переполнений стека, но вводит еще одну проблему двоичной совместимости, поскольку взаимодействие с кодом, который не был построен с помощью этой опции, может стать мутным; Я не знаю, как они планируют реализовать это точно.

1 голос
/ 26 февраля 2011

Полагаю, одно важное отличие состоит в том, что:

  • malloc - это C-способ выделения памяти;и не было никаких исключений в C
  • new - это C ++, объектно-ориентированный и все, способ;и есть исключения в C ++, и их использование более чисто .


Зачем сохранять malloc в C ++?Я полагаю, это потому, что компилятор C ++ также может работать с кодом C ...

... Но я часто слышал (от учителей, когда я еще учился в школе пару лет назад) что использование malloc в C ++ не рекомендуется, и вместо него следует использовать new.

0 голосов
/ 26 февраля 2011

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

// never throws
char* ptr = new (nothrow) char [1024*1024];

// check pointer for succeeded allocation
if ( !ptr ) { 
  ... // handle error
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...