Это безопасно для использования malloc?

Кто-то сказал мне, что выделение с malloc больше не безопасно, я не гуру C/C++, но я сделал некоторый материал с malloc и C/C++. Кто-либо знает, о каких рисках я в?

Заключение в кавычки его:

[..] Но действительно слабое место C/C++, это - безопасность и ахиллесова пята, действительно malloc и злоупотребление указателями. C/C++ это - известный небезопасный язык [..] Было бы немного приложений в том, что я не рекомендую продолжить программировать с C++."

8
задан deft_code 16 May 2010 в 05:05
поделиться

11 ответов

[...] C / C ++ это хорошо известный небезопасный язык. [...]

На самом деле это неправильно. На самом деле "C / C ++" даже не существует. Есть C и C ++ . У них общий (или, если хотите, большой) синтаксис, но они действительно очень разные языки .

Одна вещь, в которой они сильно различаются, - это способ управления динамической памятью. Способ C действительно использует malloc () / free () , и если вам нужна динамическая память, вы почти ничего не можете сделать, кроме как использовать их (или несколько братьев и сестер malloc () ).
Способ C ++ состоит в том, чтобы не (вручную) работать с динамическими ресурсами (из которых только одна память) . Управление ресурсами передается нескольким хорошо реализованным и протестированным классам, предпочтительно из стандартной библиотеки, а затем выполняется автоматически. Например, вместо того, чтобы вручную обрабатывать символьные буферы с нулевым завершением, есть std :: string , вместо того, чтобы вручную обрабатывать динамически выделяемые массивы, там std: vector , вместо того, чтобы обрабатывать вручную с открытыми файлами существует семейство потоков std :: fstream и т. д.

13
ответ дан 5 December 2019 в 04:39
поделиться

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

Сказать, что malloc небезопасно, все равно что сказать «не используйте систему X, потому что она небезопасна».

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

1
ответ дан 5 December 2019 в 04:39
поделиться

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

0
ответ дан 5 December 2019 в 04:39
поделиться

Использование malloc небезопасно, потому что невозможно написать крупномасштабное приложение и гарантировать, что каждый malloc освобождается эффективным способом. Таким образом, у вас будет множество утечек памяти, которые могут быть, а могут и не быть проблемой ... но , когда вы удваиваете free или используете неправильное delete и т.д., может возникнуть неопределенное поведение. Действительно, использование неправильного delete в C ++ обычно допускает выполнение произвольного кода.

ЕДИНСТВЕННЫЙ способ обеспечить безопасность кода, написанного на таких языках, как C или C ++, - это математически доказать всю программу с учетом ее зависимостей.

Современные безопасные для памяти языки защищены от этих типы ошибок при условии, что реализация базового языка не уязвима (что действительно редко, потому что все они написаны на C / C ++, но по мере продвижения к аппаратным JVM эта проблема исчезнет).

0
ответ дан 5 December 2019 в 04:39
поделиться

Если вы используете C, вам придется использовать malloc для выделения памяти, если только у вас нет сторонней библиотеки, которая будет выделять / управлять памятью за вас.

Конечно, ваш друг прав в том, что на C трудно писать безопасный код, особенно когда вы выделяете память и работаете с буферами. Но мы все это знаем, верно? :)

1
ответ дан 5 December 2019 в 04:39
поделиться

Это, вероятно, правда, что новый C ++ безопаснее , чем 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 () просто дает вам кусок памяти для использования; новый дополнительно вызовет подрядчика (при его наличии). Аналогично, delete вызовет деструктор (если он есть), а free () - нет. Это могло привести к проблемам, таким как неправильно инициализированные объекты (потому что конструктор не был вызван) или неосвобожденные ресурсы (потому что деструктор не был вызван).

3) C ++ 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 ( ) где возможно. (В C функция new / delete недоступна, поэтому выбор там будет очевиден.)

16
ответ дан 5 December 2019 в 04:39
поделиться

Ваш друг мог бы иметь в виду:

  • Безопасность использования указателей в целом. Например, в C ++, если вы выделяете массив char с помощью malloc, спросите, почему вы не используете строку или вектор . Указатели небезопасны, но код, содержащий ошибки из-за неправильного использования указателей, небезопасен.

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

Также возможно, что ваш друг не знает, о чем говорит. Когда кто-то говорит «X небезопасен», я отвечаю: «Каким образом?».

8
ответ дан 5 December 2019 в 04:39
поделиться

Может быть, ваш друг старше и не знаком с тем, как все работает сейчас. Раньше я думал, что C и C ++ практически одинаковы, пока я не обнаружил много нового о языке, который появился за последние 10 лет (большинство моих учителей были парнями из Bell Laboratories старой школы, которые писали в основном на C и имели лишь поверхностные знания C ++ - а инженеры Bell Laboratories изобрели C ++!). Не смейтесь над ним / ней - вы тоже можете быть там когда-нибудь!

Я думаю, вашему другу не нравится идея, что вы должны сами управлять памятью, то есть легко допускать ошибки. В этом отношении это небезопасно, и он / она прав ... Однако этот небезопасный аспект можно преодолеть с помощью хороших методов программирования, таких как RAII , и использования интеллектуальных указателей.

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

3
ответ дан 5 December 2019 в 04:39
поделиться

Это единственный способ выделения и удаления памяти в C нативно. Если вы неправильно его используете, он может быть таким же небезопасным, как и все остальное. Microsoft предоставляет некоторые "безопасные" версии других функций, которые принимают дополнительный параметр size_t - возможно, ваш друг имел в виду что-то подобное? Если это так, возможно, он просто предпочитает calloc() вместо malloc()?

2
ответ дан 5 December 2019 в 04:39
поделиться

Технически говоря, malloc никогда не был безопасным с самого начала, но, не считая этого, единственное, о чем я могу думать, это печально известный "убийца OOM" (OOM = out-of-memory), который использует ядро Linux. Вы можете почитать об этом, если хотите. В остальном, я не вижу, как malloc сам по себе небезопасен.

0
ответ дан 5 December 2019 в 04:39
поделиться

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

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

1
ответ дан 5 December 2019 в 04:39
поделиться