2010-10-03 3 views
4

Я исхожу из фона java, и я могу что-то сделать в Java, что мне нужно делать на C++, но я не уверен, как это сделать.Определить массив, а затем изменить его размер.

Мне нужно объявить массив, но на данный момент я не знаю размер. Как только я знаю размер, я задаю размер массива. Я Java я бы просто сделать что-то вроде:

int [] array; 

затем

array = new int[someSize]; 

Как это сделать в C++?

+0

Вы просто не знаете размер или еще вы знаете размер только после того, как вы что-то прочитали во время выполнения? То есть это размер постоянной времени компиляции? Есть более простые способы решить эту проблему, чем использовать новые или векторы в этом случае. –

+0

По вашему мнению, вы согласились, что, похоже, вы не думаете, что 'std :: vector' будет работать для вас. Почему это? – SingleNegationElimination

ответ

15

В C++ вы можете сделать:

int *array; // declare a pointer of type int. 
array = new int[someSize]; // dynamically allocate memory using new 

и как только вы сделали с помощью memory..de-выделить его с помощью удаления, как:

delete[]array; 
+3

Это правильно и проницательно, но на самом деле следует поощрять использование 'std :: vector' в C++.Вот для чего контейнер, и из очевидных преимуществ стандартных контейнеров, играющих хорошо с RAII и т. Д., Под скином 'std :: vector' имеет этот код внутри байта для байта. Обычно причины не использовать стандартные контейнеры имеют отношение к доступности шаблонов, заданного нестандартного компилятора и т. Д. Я не буду выдвигать этот ответ не потому, что это неправильно, а потому, что он скрывает массу важной, актуальной информации, которую вы всегда должны осознавать. – wilhelmtell

+0

Очень важно, что вы делаете 'delete [] array;' иначе вы будете утечки памяти, и это опасно –

-2

Объявляем указатель:

int * array; 
+3

Это не очень полезное предложение без лишнего контекста. –

+0

Это будет (начало) правильного ответа на C, но на C++ вы должны использовать только указатель, если у вас есть веская причина не использовать 'std :: vector' или' std :: deque'. – wilhelmtell

+2

Я предполагаю, что твердая причина не использовать 'java.util.Vector' передаст и станет твердой причиной не использования' std :: vector'. И сейчас я пробую простой ответ. Посмотрим, как это получится. – aib

25

вы хотите использовать std::vector в большинстве случаев.

std::vector<int> array; 

array.resize(someSize); 

Но если вы настаиваете на использовании new, то вы делаете на немного больше работы, чем вы делаете в Java.

int *array; 
array = new int[someSize]; 

// then, later when you're done with array 

delete [] array; 

Нет C++ автономной работы не приходят с сборщика мусора по умолчанию, поэтому delete[] требуется, чтобы избежать утечки памяти. Вы можете получить лучшее из обоих миров, используя тип интеллектуального указателя, но на самом деле просто используйте std::vector.

+0

Pfff. Удивительно, что SO-izens так же себя ведут, как и мы. +1. – Potatoswatter

+0

C++ 'std :: vector' имеет много общего с Java' java.util.ArrayList'. (Есть и различия, но сходства сильны.) –

1

Лучший способ будет для вас использовать a std::vector. Он делает все, что вам нужно, и прост в использовании и учебе. Кроме того, поскольку это C++, вы должны использовать vector вместо массива. Here - отличная причина, почему вы должны использовать контейнерный класс (вектор) вместо массива.

Векторы динамичны по размеру и растут по мере необходимости - именно то, что вы хотите.

1

Точный ответ:

char * array = new char[64]; // 64-byte array 

// New array 
delete[] array; 
array = new char[64]; 

std::vector является гораздо лучшим выбором в большинстве случаев, однако. Он делает то, что вам нужно, без ручного удаления и новых команд.

+0

Я бы сказал, что все случаи. – GManNickG

+0

GMan: За исключением изучения теории, я должен согласиться. – ssube

1

Как уже упоминалось, std::vector - это, как правило, путь. Причина в том, что вектор очень хорошо понятен, он стандартизирован для всех компиляторов и платформ, и, прежде всего, он защищает программиста от трудностей ручного управления памятью. Более того, векторные элементы должны выделяться последовательно (то есть, векторные элементы A, B, C будут отображаться в непрерывной памяти в том же порядке, в каком они были введены в вектор). Это должно сделать вектор как кэш-совместимым, как обычный динамически распределенный массив.

Хотя тот же конечный результат определенно может быть достигнуто путем объявления указатель на Int и вручную управлять памятью, это будет означать дополнительную работу:

  1. Каждый раз, когда вам нужно больше памяти, необходимо вручную выделить его
  2. вы должны быть очень осторожны, чтобы удалить все ранее выделенную память перед назначением нового значения указателя, чтобы вы застряли с огромной утечкой памятью
  3. в отличии от std::vector, этот подход не RAII содружественными. Рассмотрим следующий пример:

    void function() 
    { 
        int* array = new int[32]; 
        char* somethingElse = new char[10]; 
        // Do something useful.... No returns here, just one code path. 
        delete[] array; 
        delete[] somethingElse; 
    } 
    

Это выглядит в целости и сохранности. Но это не так. Что делать, если при попытке выделить 10 байтов для «somethingElse», у системы заканчивается память? Будет выбрано исключение типа std::bad_alloc, которое начнет разворачивать стек, ищущий обработчик исключений, пропускает инструкции удаления в конце функции. У вас есть утечка памяти. Это лишь одна из многих причин избежать ручного управления памятью на C++. Чтобы исправить это (если вы действительно это действительно хотите), библиотека Boost предоставляет кучу красивых оберток RAII, таких как scoped_array и scoped_ptr.

0

использование станд :: массив, когда размер известен во время компиляции в противном случае использовать зЬй :: вектор

#include <array> 
constexpr int someSize = 10; 
std::array<int, someSize> array; 

или

#include <vector> 
std::vector<int> array; //size = 0 
array.resize(someSize); //size = someSize 
Смежные вопросы