C создание массивов

#c #arrays

#c #массивы

Вопрос:

Почему я не могу сделать что-то подобное:

 int size = menu.size;
int list[size];
 

Есть ли что-нибудь вокруг этого вместо использования вектора? (массивы работают быстрее, поэтому я хотел использовать массивы)

Спасибо

Комментарии:

1. (массивы быстрее, поэтому я хотел использовать массивы) — Пожалуйста, расскажите нам, при каких обстоятельствах массивы быстрее и как использование a vector может вызвать узкое место в вашем коде. Как новичку, вам действительно следует избегать неверных предположений о производительности вашего кода. В подавляющем большинстве случаев вы никогда не увидите разницы в производительности и избежите различных типов ошибок, связанных с использованием необработанных массивов.

2. если вы беспокоитесь о производительности между вектором и массивом, вы лаете не на то дерево. гораздо большие потери производительности в 99,9% случаев зависят от алгоритма или ввода-вывода.

3. Да, эти ребята правы. Раньше я думал так же, как и ты. Я использую, чтобы попытаться реализовать свои собственные динамические массивы, когда я начал c . Теперь я понял, что я в основном делал то же самое, что и вектор, и векторная реализация, вероятно, быстрее и безопаснее, чем моя. Однако это не значит, что вы не должны играть с массивами в куче в учебных целях. Вы получите лучшее представление о том, как все работает, если попробуете сделать это самостоятельно.

Ответ №1:

Размер должен быть известен во время компиляции, поскольку компилятору необходимо знать, сколько места в стеке потребуется, чтобы выделить для него достаточно памяти. (Редактировать: я исправлен. В C массивы переменной длины могут быть размещены в стеке. Однако C не допускает массивов переменной длины.)

Но вы можете создавать массивы в куче во время выполнения:

 int* list = new int[size];
 

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

 delete [] list;
 

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

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

Комментарии:

1. Опять же, если ваш первый абзац был true, то VLAS не могли существовать в C.

2. Я знаю, что мой список не будет очень большим, но разве хранение чего-либо в куче не происходит медленно, так как для его извлечения им нужно обращаться к памяти? (просто чтобы я знал в будущем). Спасибо

3. @Danny: Что бы вы ни делали, элементы, которые вы хотите сохранить, в конечном итоге окажутся в памяти (будь то стек или куча). Доступ к ним из стека не будет быстрее (за исключением проблем с кэшированием). Куча требует немного больше учета, поэтому получение памяти может быть немного медленнее, но незначительно для большинства приложений. Если объявление памяти в куче становится вашим узким местом, вы можете реализовать какой-то механизм повторного использования массива (или использовать специализированный распределитель)

4. @Cameron Спасибо за информацию 🙂

Ответ №2:

Как уже говорили другие, разработчики языка C решили не разрешать массивы переменной длины, VLA, несмотря на то, что они доступны в C99. Однако, если вы готовы проделать немного больше работы самостоятельно, и вам просто отчаянно нужно выделить память в стеке, вы можете использовать alloca() .

Тем не менее, я лично использовал std::vector бы . Это проще, безопаснее, удобнее в обслуживании и, вероятно, достаточно быстро.

Комментарии:

1. 1 alloca() — это ответ, если вы действительно, действительно хотите распределять массивы динамического размера в стеке во время выполнения на C . Но будьте осторожны…. Переполнение стека! ахнуть

2. Или используйте VLAS с расширением компилятора (gcc).

Ответ №3:

C не допускает использования массивов переменной длины. Размер должен быть известен во время компиляции. Так что вы не можете этого сделать.

Вы можете использовать векторы или new .

 vector<int> list;
 

или

 int *list = new int[size];
 

Если вы выберете последнее, вам нужно будет освободить его позже:

 delete[] list;
 

массивы работают быстрее, поэтому я хотел использовать массивы

Это не так. Откуда вы это услышали?

Ответ №4:

В C длина массива должна быть известна во время компиляции, чтобы разместить его в стеке.

Если вам нужно выделить массив, размер которого вы не знаете во время компиляции, вам нужно будет выделить его в куче, используя operator new[]

 int size = menu.size;
int *list = new int[size];
 

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

 delete[] list;
 

Комментарии:

1. Смотрите мои комментарии к другим вопросам — ваш первый абзац чрезмерно решителен. Возможно создание систем, в которых размеры выделения стековой памяти могут быть определены во время выполнения.

Ответ №5:

AFAIK В C 03 нет массивов переменной длины (VLA):

вы, вероятно, хотите это сделать:

 const int size = menu.size;
int list[size]; // size is compile-time constant
 

или

 int *list = new int[size]; // creates an array at runtime;
delete[] list;             // size can be non-const
 

Ответ №6:

во-первых, векторы не намного быстрее. что касается причины, по которой вы не можете сделать что-то подобное:

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

самый простой способ — создать массив в куче: int list = new int[size]; не забудьте delete[] сделать это позже. Однако, если вы используете вектор и заранее резервируете правильный размер компилируете с оптимизацией, накладных расходов должно быть немного или совсем не должно быть.

Комментарии:

1. Одним из интересных аспектов этого в C является то, что если вы пишете int a[n] , где n объявлено через const , то вы фактически получаете VLA, т. Е. Выделение стека резервируется во время выполнения, а не во время компиляции. Это потому, что C const означает только для чтения, а не константу.

Ответ №7:

Поскольку list он размещен в стеке, его размер должен быть известен во время компиляции. Но здесь size это неизвестно до времени выполнения, поэтому размер list не известен во время компиляции.

Комментарии:

1. Если бы это было правдой, то ВЛАс не существовал бы в C.

2. В данном случае это верно, потому что это C , а не C.

3. Я хочу сказать, что проблема не в том, что list выделено в стеке. Проблема в том, что язык C не поддерживает VLAS. Это возможно, если языковой комитет решит, что они хотят это сделать. Таким образом, ваш ответ не должен говорить о том, что размер известен во время компиляции. Следует просто сказать, что вы не можете сделать это в C .