Должны ли массивы использоваться в C ++?

Посколькуstd::list а такжеstd::vector Существуют, есть ли причина использовать традиционные массивы C в C ++, или их следует избегать, какmalloc?

 Jon Purdy23 мая 2012 г., 18:58
@ Als: Этот вопрос касается различия между двумя конкретными контейнерами, в то время как этот вопрос касается различия между необработанными массивами и стандартными контейнерами в целом.

Ответы на вопрос(11)

Решение Вопроса

std::array доступен, ответ "да, массивов следует избегать". До C ++ 11 вам может понадобиться использовать массивы C для выделения массивов в автоматическом хранилище (т.е. в стеке).

 zvrba10 июн. 2012 г., 11:15
@ Nils массивы также гарантируют выравнивание. Кроме того, автоматическое распределение памяти («стек») намного быстрее, чем динамическое распределение памяти. Если я Ноу Я имеюв точк 3 элемента [например, координаты треугольника], нет смысла использовать вектор.
 Nemanja Trifunovic10 июн. 2012 г., 15:54
@ zvrba - проверять сгенерированную сборку при использовании массивов std :: array и C. Нет разницы вообще.
 zvrba10 июн. 2012 г., 10:37
std :: array - это шаблон, который влияет на большие проекты с точки зрения времени сборки и, возможно, размера кода, поскольку для каждой комбинации T, N создается экземпляр шаблона заново.
 Nowayz25 мая 2012 г., 11:59
днако @many-компиляторам все еще не хватает поддержки C ++ 11. Вам придется решить, когда лучше использовать один, а не другой, учитывая отсутствие std :: array
 Nils10 июн. 2012 г., 10:54
std :: vector гарантирует выравнивание данных по стандарту, поэтому его можно использовать практически везде. С C ++ 11 действительно нет причин использовать массивы C.

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

 James Kanze23 мая 2012 г., 13:35
но в критических для безопасности системах вы не используете новые функции компилятора (менее проверены) и не используете boost.
 11111123 мая 2012 г., 12:56
Я знаю, именно поэтому я не понизил тебя, но я думаю, что у Boost была версия, и твою собственную тоже легко катить.
 Brian McFarland10 июн. 2012 г., 14:17
Многие критически важные системы безопасности построены на старых компиляторах, которые даже не имеют новых функций компилятора, потому что изменение цепочек инструментов - это медленный и дорогой процесс, требующий тонны бумажной работы, тестирования и сертификации.
 11111123 мая 2012 г., 12:46
До C ++ 11 я бы согласился, ноstd::array<T> распределяет по стекам и в основном не имеет накладных расходов в необработанном массиве.
 Ed Heal23 мая 2012 г., 12:53
@ 111111 - Согласен. Но я знаю, что некоторые люди в этой отрасли еще не перешли на C ++ 11

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

 Konrad Rudolph23 мая 2012 г., 22:26
@ JamesWynn Не совсем.std::array имеет точно определенную семантику, построенную поверх статических массивов.
 James Wynn23 мая 2012 г., 16:43
Более фундаментально в том, что оно более основательно. Вы знаете, что собирается делать массив, std :: array может иметь причуды реализации, поскольку он опирается на стандартную библиотеку.
 leftaroundabout23 мая 2012 г., 14:35
Как массивы в стиле C более фундаментальны, чемstd::arrays? Во многих случаях оба будут скомпилированы в одну сборку.

е @ нет, Я не могу придумать причину для использования сырых массивов, скажем,vectors. Если код новый.

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

 Mike Seymour23 мая 2012 г., 12:40
@ LuchianGrigore:vector.data() в C ++ 11 или&vector.front() ранее.
 Luchian Grigore23 мая 2012 г., 12:37
@ SteveJessop вы можете получить доступ к внутреннему массиву?
 Steve Jessop23 мая 2012 г., 12:31
... но начиная с C ++ 03 вектор "фактически" имеет массив, доступ к которому вы можете получить по указателю для чтения или записи. Так что это покрывает большинство случаев кода, который ожидает указатели на массивы. Только когда этот код выделяет или освобождает массив, вы не можете использовать вектор.
 Steve Jessop23 мая 2012 г., 12:46
@ Luchian: если вектор не пустой, вы можете взять указатель на элемент (а если он пустой, вы можете передать нулевой указатель и длину 0 любой разумно написанной функции, которая принимает крайний случай буфер нулевого размера). Практически единственная цель гарантии смежности векторов, добавленной в C ++ 03, состояла в том, чтобы позволить векторам использоваться в качестве буферов в коде с указателе
 James Kanze23 мая 2012 г., 13:34
@ SteveJessop И тот факт, что многие все равно думали, что это гарантировано, и считалось предпочтительным не разочаровывать их.

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

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

std::string foo;
//  fill foo with stuff
myExternalOutputProc(foo.c_str());

это очень хорошее решение, но не

std::string foo;
//  fill foo with stuff
myExternalOutputProc(&foo);

Причина в том, что std :: string может быть реализован многими различными способами, но строка в стиле c всегда является строкой в стиле c.

 jogojapan24 янв. 2013 г., 01:35
Но эти проблемы возникают только тогда, когда вы объединяете разные реализации стандартной библиотеки в одном проекте. Это безумие. В любом нормальном фрагменте кода вполне допустимо передать, скажем, вектор по ссылке (или, в C ++ 11, переместить его) в функцию.
 user87732924 янв. 2013 г., 14:01
Мне просто нравятся плагины
 jogojapan23 янв. 2013 г., 10:54
Я думаю, что вы пытаетесь сказать: не связывайте разные объектные коды вместе, если для их создания использовались разные компиляторы / реализации стандартной библиотеки. Это, конечно, правда. Как это связано с первоначальным вопросом?
 user87732923 янв. 2013 г., 12:13
Это всего лишь советкогд использовать массивы или контейнеры STL. Сборка данных с использованием контейнера, передача его в виде массива. Для других данных, которые являются строками, у вас должно быть что-то вроде myExternalOutputProc (foo.rawPointerGet (), foo.count ());

заключенного во что-то, что будет автоматически управлять его освобождением при необходимости) передstd::vector Я могу думать о том, чтоvector не может передать права собственности на свои данные, если ваш компилятор не поддерживает C ++ 11 и конструкторы перемещения.

 Steve Jessop23 мая 2012 г., 12:50
"вектор не может передавать права собственности на свои данные" - да, в C ++ 03, используяswap.

но я бы согласился, что их роль значительно уменьшается из-за истинных структур данных из STL.

Я бы также сказал, что инкапсуляция внутри объектов должна минимизировать влияние таких выборов. Если массив является частным членом данных, вы можете поменять его местами, не затрагивая клиентов вашего класса.

std::array в C ++ 11, практически только для статических данных. Массивы в стиле C имеют три важных преимущества передstd::vector:

Они не требуют динамического размещения. По этой причине предпочтительнее использовать массивы в стиле Си, если у вас много очень маленьких массивов. Скажите что-то вроде точки n-измерения:

template <typename T, int dims>
class Point
{
    T myData[dims];
// ...
};

Как правило, можно представить, чтоdims будет очень маленьким (2 или 3),T встроенный тип double) и что вы можете в конечном итогеstd::vector<Point> с миллионами элементов. Вы определенно не хотите, чтобы миллионы динамических распределений 3 удваивались.

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

struct Data { int i; char const* s; };
Data const ourData[] =
{
    { 1, "one" },
    { 2, "two" },
    //  ...
};

Это часто предпочтительнее использования вектора (иstd::string), поскольку он избегаетвс порядок проблем инициализации; данные предварительно загружены, прежде чем какой-либо фактический код может быть выполнен.

Наконец, в связи с вышесказанным, компилятор может вычислить фактический размер массива из инициализаторов. Вы не должны считать их.

Если у тебя есть доступ к C ++ 11,std::array решает первые две проблемы и, безусловно, должен использоваться в первом случае вместо массивов в стиле C. Однако он не относится к третьему, и наличие в компиляторе массива в соответствии с количеством инициализаторов все еще является веской причиной для предпочтения массивов в стиле

 Jon Purdy23 мая 2012 г., 19:02
@ KonradRudolph: Конечно, это так. Андреас спрашивает: «Следует ли использовать массивы в C ++?», На что Джеймс отвечает: «Определенно, хотя сstd::array в C ++ 11 [они должны использоваться] практически только для статических данных ».
 James Kanze23 мая 2012 г., 14:56
@ JoeWreschnig Изменение, которое вы легко можете забыть. Если вы добавляете элемент, компилятор должен жаловаться, но если вы его удалите, вы получите дополнительный, 0 инициализированный элемент в конце. Я до сих пор широко использую массивы в стиле C для статических данных такого рода.
 Konrad Rudolph23 мая 2012 г., 17:03
Третий пункт может быть решен довольно элегантно с помощьюmake_array функция, похожий наmake_pair т. @Р. Мартиньо Фернандес.
 user7975823 мая 2012 г., 14:51
нициализация массива в стиле @ C также устраняет необходимость повторяться.int i[] = { 1, 2, 3 }; продолжает работать сint i[] = { 1, 2, 3, 4 };. array<int, 3> необходимо вручную изменить наarray<int, 4>.
 Konrad Rudolph23 мая 2012 г., 16:37
Первое предложение не имеет смысла.

array вc++ дает вам фиксированный размер быстрой альтернативы динамического размераstd::vector а такжеstd::list. std :: массив является одним из дополнений вc++11. Он обеспечивает преимущества контейнеров std, в то же время обеспечивая семантику агрегированных типов массивов в стиле C.

Так вc++11 я бы обязательно использовалstd::array, где это требуется, над вектором. Но я бы избегал массива в стиле C вC++03.

: для размещения массивов в стеке и std :: vector для кучи. Но ни один из них не поддерживает неродное выравнивание. Если вы используете какой-либо числовой код, для которого вы хотите использовать инструкции SSE или VPX (таким образом, требуя выравнивания по 128 или 256 байт соответственно), массивы C по-прежнему кажутся вам лучшим выбором.

Ваш ответ на вопрос