Я динамически выделяю память для массива в функции. Мой вопрос: когда функция завершает работу, освобождается ли память?
код:
void f(){
cv::Mat* arr = new cv::Mat[1];
...
}
Нет. Вы должны освободить его, позвонив
delete[] arr;
Но вы должны спросить себя, нужно ли выделять динамически. Это не требует явного управления памятью:
void f(){
cv::Mat arr[1];
...
}
Если вам нужен массив динамического размера, вы можете использовать std::vector
, Вектор будет внутренне распределяться динамически, но позаботится об отмене выделения его ресурсов:
void f(){
std::vector<cv::Mat> arr(n); // contains n cv::Mat objects
...
}
Нет, память выделена с помощью new
не освобождается автоматически, когда указатель выходит из области видимости.
Тем не менее, вы можете (и должен) использовать C ++ 11 unique_ptr
, который обрабатывает освобождение памяти, когда она выходит из области видимости:
void f(){
std::unique_ptr<cv::Mat[]> arr(new cv::Mat[1]);
...
}
C ++ 11 также обеспечивает shared_ptr
для указателей вы можете скопировать. Современный C ++ должен стремиться использовать эти «умные указатели», поскольку они обеспечивают более безопасное управление памятью практически без снижения производительности.
Нет. Каждый звонок new
должно быть сопоставлено с призывом к delete
где-то.
В твоем случае arr
iteself переменная с автоматической продолжительностью хранения Это означает, что arr
сам будет уничтожен, когда выйдет за рамки. Однако вещь, которая arr
указывает на нет, потому что тот переменная, которая не имеет автоматической продолжительности хранения.
Дело в том, что arr
Сама автоматическая продолжительность хранения может быть использована в ваших интересах, оборачивая необработанный указатель в класс, который уничтожает сохраненный указатель при уничтожении автоматического объекта. Этот объект использует идион, известный как RAII реализовать так называемый «умный указатель». Поскольку это очень распространенное требование в хорошо спроектированных приложениях, стандартная библиотека C ++ предоставляет ряд классов интеллектуальных указателей, которые вы можете использовать. В C ++ 03 вы можете использовать
std::auto_ptr
В С ++ 11 auto_ptr
был объявлен устаревшим и заменен несколькими другими лучшими умными указателями. Среди них:
std::unique_ptr
std::shared_ptr
В целом, лучше использовать умные указатели вместо сырых («тупых») указателей, как здесь.
Если в конечном итоге вам нужны массивы динамического размера, поддерживаемые C99, вы должны знать, что C ++ не имеет прямой поддержки для них. Некоторые компиляторы (в частности, GCC) предоставляют поддержку динамически изменяемых массивов, но это специфичные для компилятора языковые расширения. Чтобы иметь что-то, что приближается к динамически изменяемому массиву при использовании только переносимого, совместимого со стандартами кода, почему бы не использовать std::vector
?
Редактировать: Присвоение массиву:
В ваших комментариях вы описываете способ, которым вы присваиваете этот массив, который я принял, чтобы обозначить что-то вроде этого:
int* arr = new int[5];
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
Если это так, вы можете сделать то же самое, используя vector
позвонив vector::operator[]
, В этом случае синтаксис очень похож на тот, что вы использовали выше. Единственная настоящая «ошибка» в том, что с vector
Размеры даны в натуральном выражении, вы должны убедиться, что vector
имеет по крайней мере N
элементы, прежде чем пытаться назначить элемент в позиции N-1
, Это может быть достигнуто несколькими способами.
Вы можете создать vector
с N
элементы с самого начала, в этом случае каждый будет инициализирован значением:
vector<int> arr(5); // creates a vector with 5 elements, all initialized to zero
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
Вы можете resize
вектор по факту:
vector<int> arr; // creates an empty vector
arr.resize(5); // ensures the vector has exactly 5 elements
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
Или вы можете использовать различные алгоритмы, чтобы заполнить вектор элементами. Одним из таких примеров является fill_n
:
vector<int> arr; // creates empty vector
fill_n(back_inserter(arr), 5, 0); // fills the vector with 5 elements, each one has a value of zero
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
Нет, конечно нет.
Для каждого new
вам нужен именно один delete
,
Для каждого new[]
вам нужен именно один delete[]
,
Так как у вас нет соответствия delete[]
, ваша программа не работает
(По этой причине взрослый способ использования C ++ не должен использовать new
или указатели на всех. Тогда у вас нет этих проблем.)
Нет. Массив, выделенный в куче, вам придется удалить его, прежде чем он выйдет из области видимости:
void f() {
cv::Mat * arr = new cv::Mat[1];
// ...
delete [] arr;
}