Создание введенного пользователем размера массива с помощью оператора new

У меня есть несколько вопросов, связанных с массивом. Я изучил, что размер массива должен быть постоянным при объявлении / компилятор должен знать его значение. Но используя компилятор GNU GCC (стандартный фильтр C ++ 11), я могу прекрасно скомпилировать и запустить программу, используя переменную в качестве размера массива, при динамическом объявлении указанного массива (используя new)

int num;
cout << "How big an array? ";
cin >> num;
int *arr = new int [num];

Ques1) Это считается стандартом? Мои профессионалы противоречивы.

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

Ques3) Опять же, если это выражение стандартно, то возможно ли использовать его внутри функции — например, используя функцию для создания такого массива? (если так, то как?)

(PS: Привет, я новичок здесь и еще новичок в C ++)

8

Решение

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);
6

Другие решения

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

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

Статический массив

Массив, объявленный в глобальной области видимости, должен иметь постоянный размер.

int arr[5];

Автоматический массив

Массив, автоматически размещаемый внутри функции, должен иметь постоянный размер (за исключением, см. Ниже).

void f() {
int arr[5];
}

Динамический массив

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

new int[5];
new int[n * 4];

Расширение GCC

Исключением является то, что GCC позволяет использовать переменная объявить размер автоматического массива:

void f(int n) {
int arr[n];
}

Тем не менее, это использование не является стандартным.

3

Вопрос 1 — оператор ‘new’ используется для динамического размещения, я имею в виду, когда вы ранее не знаете, каков размер массива, поэтому проблем нет, вы можете это сделать! Я думаю, что ваши профессионалы путают с синтаксисом C, где new также не существует и не может создавать такие вещи, как: int p [n]; например.

Вопрос 2 — Нет, невозможно увеличить размер массива, созданного с помощью оператора new. Вы должны выделить другой массив и скопировать данные. Вы можете рассмотреть использование вектора, чтобы сделать это легко.

Вопрос 3 — я не понимаю, зачем это делать, но это возможно ..

int* createarray(int size)
{
return new int[size];
}int main()
{
int *p = createarray(10);
}
0

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 }
0

В дополнение к другим ответам:

векторы

(Согласовано с вектором для динамического изменения размера):

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
  • Если новый размер больше старого, дополнительные элементы будут инициализированы равными 5 (или 0 в случае int, если второй параметр не используется), а древние элементы останутся без изменений.
  • Если новый размер меньше старого, он усекается.

Массивы

Примечание : (около стек а также куча распределение)

Способ 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];
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector