У меня есть несколько вопросов, связанных с массивом. Я изучил, что размер массива должен быть постоянным при объявлении / компилятор должен знать его значение. Но используя компилятор GNU GCC (стандартный фильтр C ++ 11), я могу прекрасно скомпилировать и запустить программу, используя переменную в качестве размера массива, при динамическом объявлении указанного массива (используя new
)
int num;
cout << "How big an array? ";
cin >> num;
int *arr = new int [num];
Ques1) Это считается стандартом? Мои профессионалы противоречивы.
Ques2) Если это является Стандартный, в таком случае, возможно ли расширить размер массива (или любого массива) после создания?
Ques3) Опять же, если это выражение стандартно, то возможно ли использовать его внутри функции — например, используя функцию для создания такого массива? (если так, то как?)
(PS: Привет, я новичок здесь и еще новичок в C ++)
Ques1) Это считается стандартом? Мои профессионалы противоречивы.
Да, это полностью верно. Обратите внимание, что вам нужно явно удалить память, указанную arr
используя оператор delete[]
, Гораздо лучше использовать std::vector<int>
который будет выполнять управление памятью для вас.
Вы можете ошибиться с массивами переменной длины (VLA), которые не допускаются в C++
:
// same num as the one in your example
int arr[num]; // ERROR
Это действительно в C
но недействительным в C++
(C ++ 14 будет включать VLA, хотя они будут иметь некоторые различия с C
Влас).
Ques2) Если это стандарт, в таком случае, возможно ли продлить
размер массива (или любого массива) после создания?
Нет, вы не можете продлить это. Вы можете выделить больший массив, скопировать элементы и удалить предыдущий. Опять же, это делается автоматически, если вы используете std::vector<int>
,
Ques3) Опять же, если это выражение является стандартным, то возможно ли
использовать его в функции — например. используя функцию для создания такого
массив? (если так, то как?)
Да, конечно:
int *allocate(size_t size) {
return new int[size];
}
Но опять использование std::vector
:
int num;
cout << "How big an array? ";
cin >> num;
std::vector<int> arr(num); // num elements, all of them initialized to 0
// insert 42 at the end. reallocations(if any) are done automatically
arr.push_back(42);
Я изучил, что размер массива должен быть постоянным при объявлении / компилятор должен знать его значение.
Ну, это правда, но только для статический или же автоматический массивы. Вы выделяете динамический массив в куче, который отличается.
Массив, объявленный в глобальной области видимости, должен иметь постоянный размер.
int arr[5];
Массив, автоматически размещаемый внутри функции, должен иметь постоянный размер (за исключением, см. Ниже).
void f() {
int arr[5];
}
Динамический массив, выделенный в куче с new
может иметь любой размер, постоянный или переменный.
new int[5];
new int[n * 4];
Исключением является то, что GCC позволяет использовать переменная объявить размер автоматического массива:
void f(int n) {
int arr[n];
}
Тем не менее, это использование не является стандартным.
Вопрос 1 — оператор ‘new’ используется для динамического размещения, я имею в виду, когда вы ранее не знаете, каков размер массива, поэтому проблем нет, вы можете это сделать! Я думаю, что ваши профессионалы путают с синтаксисом C, где new также не существует и не может создавать такие вещи, как: int p [n]; например.
Вопрос 2 — Нет, невозможно увеличить размер массива, созданного с помощью оператора new. Вы должны выделить другой массив и скопировать данные. Вы можете рассмотреть использование вектора, чтобы сделать это легко.
Вопрос 3 — я не понимаю, зачем это делать, но это возможно ..
int* createarray(int size)
{
return new int[size];
}int main()
{
int *p = createarray(10);
}
Q1: это считается стандартом?
Учитывая определение int n = 42, новый float [n] [5] является правильно сформированным (потому что п является выражением
noptr-new-декларатор), но новый float [5] [n] не сформирован (потому что n
не постоянное выражение).
—5.3.4.6, N3242Если выделенный тип является типом массива, функция выделения
name это оператор new [] и имя функции освобождения
Оператор удаления [].
—5.3.4.8, N3242
new T[5]
приводит к вызовуoperator new[](sizeof(T)*5+x)
Здесь x и y — неотрицательные неопределенные значения, представляющие накладные расходы на выделение массива;
—5.3.4.12, N3242
Q2: Если это стандарт, в таком случае, возможно ли расширить размер массива (или любого массива) после создания?
Частично нет или не рекомендуется.
когда функция выделения возвращает значение, отличное от нуля, это должен быть указатель на блок хранения
в котором место для объекта было зарезервировано. В основном распределение происходило в куче, и там может не быть больше смежный Осталась память, что важно для массива.
Если вам нужно сделать это и провести опрос памяти, используйте оператор размещения размещения, вы можете сделать это частично, но сейчас вы делаете то, что делает дизайнер распределителя, и рискуете испортить внутреннюю память.
Q3: используя функцию для создания такого массива? (если так, то как?)
Объекты, созданные новым выражением, имеют динамическую продолжительность хранения
(3.7.4). [Примечание: время жизни такого объекта не обязательно
ограничено областью, в которой он создан. — конец примечания] —5.3.4.1, N3242
В остальном, как спроектировать такую функцию, чтобы удовлетворить ваши потребности, даже использовать шаблон.
1 template<typename T>T* foo(std::size_t size){
2 return new T[size] ;
3 }
векторы
(Согласовано с вектором для динамического изменения размера):
std::vector<int> v;
v.push_back(1);
v.push_back(1);
v.resize(v.size()+10, 5); // Greater resized
v.resize(v.size()-1); // Lower resized
Массивы
Примечание : (около стек а также куча распределение)
Способ array
может привести к значительным результатам (см. это очень интересно обсуждение):
// Create 500 bytes on the heap
char *pBuffer = new char[500]; // or malloc in C
// Create 500 bytes on the stack
char buffer[500];