Безопасно ли использовать malloc?
кто-то сказал мне, что выделение с malloc больше не безопасно, я не гуру C/C++, но я сделал некоторые вещи с malloc и C/C++. Кто-нибудь знает, чем я рискую?
цитировать:
[..] Но действительно слабое место C / C++ - это безопасность, а ахиллесова пята-это действительно Маллок и злоупотребление указателями. C / C++ это хорошо известный небезопасный язык. [..] Было бы несколько приложений в том, что я бы не рекомендовал продолжать Программирование с C++."
11 ответов
[...] C / C++ это хорошо известный небезопасный язык. [...]
на самом деле, это неправильно. на самом деле "C/C++" даже не существует. здесь C, и C++. Они разделяют некоторый (или, если хотите, много) синтаксис, но они действительно разные языки.
одна вещь, в которой они сильно отличаются, - это их путь для управления динамической памятью. Путь C действительно использует malloc()
/free()
и если вам нужна динамическая память, вы можете только использовать их (или несколько братьев и сестер malloc()
).
путь C++ заключается в том, чтобы не (вручную) работать с динамическими ресурсами (из которых память только одна)на всех. Управление ресурсами передается нескольким хорошо реализованным и проверенным классам, желательно из стандартной библиотеки, а затем делается автоматически. Например, вместо того, чтобы вручную обрабатывать буферы символов с нулевым завершением, есть std::string
, вместо того, чтобы вручную работать с динамически распределенными массивами, там std:vector
, вместо того, чтобы вручную работать с открытыми файлами, есть std::fstream
семейные потоков и т. д.
вероятно, это правда, что c++'s new
и безопасное чем malloc()
, но это автоматически не делает malloc()
более небезопасно, чем раньше. Ваш друг сказал, почему он считает это небезопасным?
однако, вот несколько вещей, на которые вы должны обратить внимание:
1) С C++, вы должны быть осторожны, когда вы использовать malloc()
/free()
и new
/delete
бок-о-бок в то же программа. Это возможно и допустимо, но все, что было выделено malloc()
должен быть освобожден с free()
, а не delete
. Аналогично, все, что было выделено new
должен быть освобожден с delete
, а не free()
. (Эта логика идет еще дальше: если вы выделяете массив с new[]
, вы должны освободить его с delete[]
и не только delete
.) Всегда использовать соответствующие аналоги для распределения и освобождения, в объект.
int* ni = new int;
free(ni); // ERROR: don't do this!
delete ni; // OK
int* mi = (int*)malloc(sizeof(int));
delete mi; // ERROR!
free(mi); // OK
2) malloc()
и new
(снова говоря о C++) не делайте то же самое. malloc()
просто дает вам кусок памяти для использования; new
дополнительно вызовите contructor (если имеется). Аналогично,delete
вызовет деструктор (если он доступен), в то время как free()
не будет. Это может привести к проблемам, таким как неправильно инициализированные объекты (поскольку конструктор был вызван) или несвободные ресурсы (поскольку деструктор не вызывался).
3) С++new
также заботится о выделение нужного объема памяти для указанного типа, в то время как вам нужно рассчитать это самостоятельно с malloc()
:
int *ni = new int;
int *mi = (int*)malloc(sizeof(int)); // required amount of memory must be
// explicitly specified!
// (in some situations, you can make this
// a little safer against code changes by
// writing sizeof(*mi) instead.)
вывод:
В C++, new
/delete
должно быть предпочтительнее malloc()
/free()
там, где это возможно. (In C,new
/delete
нет в наличии, поэтому выбор был бы очевиден там.)
ваш друг может говорить о:
безопасность использования указателей в целом. Например, в C++ , если вы выделяете массив char с помощью malloc, спросите, почему вы не используете
string
илиvector
. Указатели не являются небезопасными, но код, который глючит из-за неправильного использования указателей.что-то про malloc в частности. Большинство ОС очищают память перед тем, как передать ее процессу, по соображениям безопасности. Иначе, конфиденциальные данные из одного приложения могут быть переданы в другое приложение. На Осах, которые этого не делают, вы можете утверждать, что есть неуверенность, связанная с
malloc
. Это действительно больше связано сfree
.
также возможно, что ваш друг не знает, о чем он говорит. Когда кто-то говорит: "X небезопасен", мой ответ: "каким образом?".
может быть, ваш друг старше и не знаком с тем, как все работает сейчас - я раньше думал, что C и c++ были фактически одинаковыми, пока я не обнаружил много новых вещей о языке, которые вышли за последние 10 лет (большинство моих учителей были старой школы Bell Laboratories ребята, которые писали в основном на C и имели только поверхностное знание C++-и инженеры Bell Laboratories изобрели C++!). Не смейся над ним/над ней - вы могли бы быть там когда-нибудь тоже!
I подумайте, что вашему другу неудобно с идеей, что вы должны делать свое собственное управление памятью - т. е. легко совершать ошибки. В этом отношении она небезопасна, и он/она прав... Однако этот небезопасный аспект можно преодолеть с помощью хороших методов программирования, таких как RAII и с помощью смарт-указатели.
для многих приложений, однако, автоматизированная сборка мусора, вероятно, прекрасна, и некоторые программисты путаются в том, как работают указатели, так как получение новых, неопытных разработчиков для эффективного программирования на C / C++ без некоторой подготовки может быть затруднено. Возможно, поэтому ваш друг считает, что C/C++ следует избегать.
Это единственный способ выделить и освободить память в C изначально. Если вы злоупотребляете им, он может быть таким же небезопасным, как и все остальное. Microsoft предоставляет некоторые "безопасные" версии других функций, которые принимают дополнительный параметр size_t - может быть, ваш друг имел в виду что-то подобное? Если это так, возможно, он просто предпочитает calloc() над malloc()?
Если вы используете c, вы должны использовать malloc
для выделения памяти, если у вас нет сторонней библиотеки, которая будет выделять / управлять вашей памятью для вас.
конечно, ваш друг имеет точку зрения, что трудно писать безопасный код в C, особенно когда вы выделяете память и имеете дело с буферами. Но мы все это знаем, верно? :)
что он, возможно, хотел предупредить вас об использовании указателей. Да, это вызовет проблемы, если вы не понимаете как это работает. В противном случае спросите, что имел в виду ваш друг, или попросите его дать ссылку, подтверждающую его утверждение.
сказав, что malloc
небезопасно, это как сказать:"не используйте систему X, потому что она небезопасна".
до этого используйте malloc
в C, и new
в C++.
Если вы используете malloc
в C++ люди будут выглядеть злыми на вас, но это нормально в очень конкретном случаи жизни.
нет ничего плохого с malloc, как таковой. Ваш друг, по-видимому, означает, что ручное управление памятью небезопасно и легко приводит к ошибкам. По сравнению с другими языками, где память управляется автоматически сборщиком мусора (не то, что невозможно иметь утечки - в настоящее время никого не волнует, очищается ли программа, когда она завершается, важно то, что что-то не захватывает память во время работы программы).
конечно, на C++ вы бы не очень коснитесь malloc вообще (потому что он просто функционально не эквивалентен новая и просто не делает то, что вам нужно, предполагая, что большую часть времени вы не хотите просто получить сырую память). И кроме того, вполне возможно программировать, используя методы, которые почти полностью исключают возможность утечек памяти и коррупции (RAII), но для этого требуется экспертиза.
Технически говоря, malloc
никогда не был безопасным для начала, но в стороне, единственное, что я могу придумать, это печально известный "убийца ум" (OOM = out-of-memory), который использует ядро Linux. Ты можешь!--3-->читайте об этом если вы хотите. Кроме этого, я не вижу, как небезопасна.
В C++ нет такой проблемы, если вы придерживаетесь хороших соглашений. В C, ну, практика. Сам по себе Malloc не является изначально небезопасной функцией - люди просто могут справиться с ее результатами неадекватно.
не безопасно использовать malloc, потому что невозможно написать крупномасштабное приложение и обеспечить, чтобы каждый malloc был освобожден в эффективное порядке. Таким образом, у вас будут тонны утечек памяти, которые могут быть или не быть проблемой... но, когда вы дважды free
, или используйте неправильный delete
etc, неопределенное поведение может привести. Действительно, используя неправильный delete
в C++ обычно допускает выполнение произвольного кода.
на только путь чтобы код, написанный на языке C или C++, был безопасным, нужно математически доказать всю программу с учетом ее зависимостей.
современные языки, безопасные для памяти, безопасны от этих типов ошибок, пока базовая языковая реализация не уязвима (что действительно редко, потому что все они написаны на C/C++, но по мере продвижения к аппаратным JVMs эта проблема исчезнет).