Мне было любопытно вот это:
В чем разница между:
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
и:
char Buffer[MAX_BUF];
Мне было любопытно вот это:
В чем разница между:
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
и:
char Buffer[MAX_BUF];
Случай 1: В
char Buffer[MAX_BUF];
Buffer
– это массив размера MAX_BUF
. Метод распределения называется VLA.
Случай 2: В
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
Buffer
– это указатель, которому выделяется память размером MAX_BUF
, что равно 1000
.
и массив не совпадает с указателем, и C-FAQ имеет очень хорошую коллекцию с подробным описанием причин.
Основное различие с точки зрения удобства использования и поведения:
malloc()
d должна быть free()
d. [Предоставлено: Джорджи]Примечание. Вики
Например, компилятор C GNU выделяет память для VLA в стеке.
char* Buffer = malloc(MAX_BUF);
создает указатель char
Buffer
, динамически выделяет MAX_BUF
байт памяти через malloc
и заставляет Buffer
указывать на начало выделенного пространства. Эта память выделяется в куче.
char Buffer[MAX_BUF];
создает массив Buffer
размера MAX_BUF
, который может содержать максимум MAX_BUF
символов. Обратите внимание, что вы создаете массив переменной длины (функция, представленная в C99), поскольку MAX_BUF
является переменной. Этот массив может быть создан в стеке.
MAX_BUF
не является константой времени компиляции.
- person Jonathan Leffler; 03.07.2015
Я добавлю немного информации с точки зрения управления памятью, в дополнение к тому, что сказали другие.
1) Основное отличие здесь:
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
Вам нужно управлять выделенной памятью вручную, например, освободить Buffer
, когда вы закончите ее использовать. Если вы забудете free
его (или освободите дважды), это может привести к проблемам.
2) Со вторым случаем:
char Buffer[MAX_BUF];
Вам не нужно ничего освобождать. Он будет уничтожен автоматически. Следовательно, вы избегаете задачи обработки памяти, что хорошо. Вы всегда должны пытаться оценить, какой подход вам нужен.
Некоторые моменты.
free()
угол, который пропустили ни я, ни @coolguy. :-)
- person Sourav Ghosh; 03.07.2015
Наиболее заметным отличием является масштаб. Массив VLA будет действителен только внутри области, в которой он объявлен, в то время как динамический массив будет доступен везде в программе, пока вы не вызовете free()
.
На практике VLA могут быть быстрее, чем динамическая память, если компилятор использует выделение стека для VLA. Однако стандарт C не указывает, где выделяется VLA.
(Теоретически компилятор может выделить VLA в куче, но тогда компилятор также будет отвечать за очистку. Я не думаю, что такие решения существуют. Каждый компилятор, который я использовал, всегда объявлял VLA в стеке. )
Это означает, что VLA не подходят для хранения больших объемов данных: вы рискуете переполнить стек. Однако это не проблема, когда вы используете динамическую память.
VLA не обладают такой переносимостью, как динамические массивы, поскольку ужасно старые компиляторы не поддерживают VLA. Теоретически новые компиляторы C11 также не должны поддерживать VLA, хотя на данный момент я знаю, что ни один компилятор не был настолько глуп, чтобы отказаться от этой поддержки.
Сравнение/резюме:
MAX_BUF
этоconst
? - person juanchopanza   schedule 03.07.2015C++
переменнаяconst
является константой, но вC
переменнаяconst
на самом деле имеетconst
квалификацию, а не фактическую константу. Итак, второй - VLA, поправьте меня, если я ошибаюсь. - person Sourav Ghosh   schedule 03.07.2015C++
навыки ужасны, в этом случае я почти невидим. Просто случайно знаю несколько случаев, например этот. :-) - person Sourav Ghosh   schedule 03.07.2015