Я только начал изучать С++. Я изучил простой способ объявления массивов, и теперь я запутался в использовании
int* foo = new int[n];
и чем он отличается от
int foo [n];
Я пробовал тестировать с кодом, но не нашел никакой разницы. Я читал из источников, что использование «нового» требует, чтобы я вручную освобождал память после того, как она мне больше не нужна. В этом случае нет никакого преимущества в использовании «нового» или динамического выделения памяти вообще. Я что-то упустил здесь?
Я попытался запустить это:
#include <iostream>
int main() {
int n;
std::cout << "array size" ;
std::cin >> n ;
std::cout << n ;
int foo [n]; //line A
// int* foo = new int[n]; //line B
foo[6] = 30;
std::cout<<foo[6]<<std::endl;
}
Комментирование строки B для запуска строки A или наоборот дало точно такой же результат.
Только один из них разрешен стандартом С++ (первый). Массивы переменной длины — это расширение компилятора, которое работает не для всех компиляторов. Существуют классы, которые позаботятся о выделении (освобождении) памяти за вас, например std::vector
. Я рекомендую использовать этот класс, так как в дополнение к управлению памятью он также имеет множество других удобных функций, таких как копирование, изменение размера, вставка и т. д.
int foo [n];
не является стандартным С++. Некоторые компиляторы позволяют использовать его как расширение, но не все. Поэтому вы не должны использовать его, кроме как в очень редких случаях. Пожалуйста, попробуйте полностью избегать c-массивов и вместо этого используйте std::vector
.
то, что сказал @fabian, плюс в стандартной библиотеке есть множество оптимизированных алгоритмов, которые работают с интерфейсами таких контейнеров
Кроме того, int* foo = new int[n];
делает 3 вещи: 1) создает переменную foo типа int*; 2) Он создает совершенно отдельный (безымянный) динамический массив int; 3) Он инициализирует переменную foo, чтобы она указывала на первый элемент (безымянного) динамического массива. Таким образом, ваш второй вариант (кроме того, что он не является частью стандартного языка) будет делать что-то другое.
Распространенная трудность, с которой сталкиваются люди, впервые изучающие C++, — это понимание разницы между указателем и массивом. Это не одно и то же! int* foo
— это указатель. int foo [n]
— это массив.
Я только начал изучать С++. Ключевое слово new
— это расширенная концепция современного C++, и ее следует изучить после того, как вы освоите основы. (Через пару лет.) Как только вы узнаете о new
, в современном C++ вам не нужно будет его использовать. Вместо этого вы должны полагаться на интеллектуальные указатели (например, std::unique_ptr
через std::make_unique
) и стандартные контейнеры библиотеки C++ (например, std::vector
).
Есть несколько способов, которыми они отличаются. Сначала поговорим об этом:
int n = 10;
int array[n];
Это не является частью стандарта ANSI C++ и может поддерживаться не всеми компиляторами. Не стоит на это рассчитывать. Представьте себе этот код:
int n = 10;
int array[n];
n = 20;
Насколько большой array
?
Вот как вы можете это сделать (но это все еще проблематично):
int n = 10;
int * array = new int[n];
Теперь это законно. Но вы должны помнить позже:
delete [] array;
array = nullptr;
Теперь есть еще два отличия. Первый выделяет место в стеке. Второй выделяет место в куче и сохраняется до тех пор, пока вы его не удалите (не вернете). Таким образом, второй может вернуть массив из функции, а первый не может, так как он исчезает при выходе из функции.
ОДНАКО... Вам настоятельно не рекомендуется делать ни то, ни другое. Вместо этого вы должны использовать класс контейнера.
#include <array>
std::array<int, n> array;
Преимущества этого:
Вариант использования OP, по-видимому, предназначен для определения размера во время выполнения, который будет std::vector. std::array можно использовать только тогда, когда размер можно определить во время компиляции.
int foo [n]
недействителен в С++, посколькуn
не является константой времени компиляции.