동적으로 함수의 배열에 메모리를 할당하고 있습니다. 내 질문은 : 일단 함수가 실행을 마친 메모리가 해제됩니다?동적 배열이 범위를 벗어날 때 메모리가 해제됩니까
코드 :
void f(){
cv::Mat* arr = new cv::Mat[1];
...
}
동적으로 함수의 배열에 메모리를 할당하고 있습니다. 내 질문은 : 일단 함수가 실행을 마친 메모리가 해제됩니다?동적 배열이 범위를 벗어날 때 메모리가 해제됩니까
코드 :
void f(){
cv::Mat* arr = new cv::Mat[1];
...
}
아니, 아니다 (그런 이유로, C의 ++를 사용하는 성인 방법은 전혀. 그럼 당신은 그 문제가 발생하지 않습니다. new
또는 포인터를 사용하지 않는 것입니다). 전화로 무료로해야합니다.
delete[] arr;
하지만 동적으로 할당해야하는지 여부를 스스로 물어야합니다. 당신이 동적 크기의 배열을해야하는 경우
void f(){
cv::Mat arr[1];
...
}
, 당신은 std::vector
을 사용할 수이 명시 적으로 메모리 관리를 필요로하지 않을 것이다. 벡터는 내부적으로 동적으로 할당되지만, 처리 걸릴 것입니다 그것의 자원을 드을-할당 :
void f(){
std::vector<cv::Mat> arr(n); // contains n cv::Mat objects
...
}
그러나 배열의 크기를 동적으로 조정할 수도 없습니다 (적어도 C++ 표준에서는 gcc가 동적 크기 배열을 확장으로 제공한다는 것을 알고 있습니다). –
@ slavik262 감사합니다. 나는 'vector'라는 예제를 추가했다. OP의 예제는 컴파일 시간 상수 '1'을 사용하지만. – juanchopanza
아니, 물론 아니지.
new
마다 정확히 delete
이 필요합니다.
new[]
마다 정확히 delete[]
이 필요합니다.
일치하는 숫자가 delete[]
이 아니므로 프로그램이 손상되었습니다.
는
이상한 downvote ... – juanchopanza
"그 이유로 성인 C++을 사용하는 방법은 새로운 포인터 나 포인터를 사용하지 않는 것입니다. 그런 다음에는 문제가 없습니다. " 뭐? 힙을 사용하지 않을 것을 제안합니까? –
@ slavik262 : 물론 아닙니다. 하지만 나는 수동으로 힙 **을 사용하지 않기를 강력하게 권합니다 **! 라이브러리 기능이 더 우수하고 안전합니다. –
번호 배열은 힙에 할당이 범위를 벗어나하기 전에, 당신은 그것을 삭제해야합니다 :
를void f() {
cv::Mat * arr = new cv::Mat[1];
// ...
delete [] arr;
}
새로운 C++ 코드는 명시 적으로'delete' 사용을 피하려고 노력해야합니다 -'unique_ptr'과'shared_ptr'은 자동으로 그것을 수행하고보다 나은 소유권 의미를 제공합니다. –
아니요, new
을 사용하여 할당 된 메모리는 포인터가 범위를 벗어날 때 자동으로 해제되지 않습니다. 이 범위를 벗어나면
그러나, 당신은 (그리고 는한다) 메모리를 해제 핸들을 C++ (11)의 unique_ptr
을 사용할 수 있습니다
void f(){
std::unique_ptr<cv::Mat[]> arr(new cv::Mat[1]);
...
}
C++ (11)는 포인터에 대한 shared_ptr
제공하면 복사하고 싶을 수도 있습니다. 현대의 C++은 성능에 거의 영향을 미치지 않고 안전한 메모리 관리를 제공하므로 이러한 "스마트 포인터"를 사용하도록 노력해야합니다.
아니 C++ 11 for me :(gcc를 설치했는데 apt-get을 사용하여 최신의 멋진 것을 제공 하겠지만 unique_ptr은 존재하지 않습니다. – Aly
@Aly,'g ++'를 호출 할 때' g ++ -std = C++ 11' 또는'g ++ -std = C++ 0x'.이 중 하나가 'unique_ptr'을 활성화해야합니다 .. –
아니요. new
에 대한 모든 전화는 delete
에 대한 전화와 일치해야합니다.
귀하의 경우 arr
iteself은 자동 저장 기간이있는 변수입니다. 즉, arr
자체가 범위를 벗어나면이 파괴됩니다. 그러나 arr
이 가리키는 것은 이므로은 자동 저장 기간이없는 변수입니다.
arr
자체에 자동 저장 기간이 있다는 사실은 자동 개체가 파괴되었을 때 저장된 포인터를 파괴하는 클래스에서 원시 포인터를 래핑하여 사용자의 이점을 활용할 수 있습니다. 이 객체는 RAII이라는 idion을 사용하여 소위 "스마트 포인터"를 구현합니다. 이것은 잘 설계된 응용 프로그램에서 매우 공통적 인 요구 사항이므로 C++ 표준 라이브러리는 사용할 수있는 여러 가지 스마트 포인터 클래스를 제공합니다. C++ 03에서는, 당신은에서
std::auto_ptr
을 사용할 수 있습니다 C++ 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
이 다이나믹하게 크기 때문에 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;
을 각 값 초기화 될 것입니다 경우에 얻을 - 이동에서 vector
N
에 항목을 만들 수 있습니다
또는 다양한 알고리즘을 사용하여 벡터로 요소를 채울 수 있습니다. 그러한 예로는 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;
안녕하세요, 무작위 방식으로 배열에 할당하기 때문에 벡터를 사용하지 않습니다. . 배열 5 크기 경우 arr [3] arr [1] 등 벡터 함께 시도 할 때 그냥 예외없이 프로그램을 종료 할 설정할 수 있습니다. (.C++ 11 std :: auto_ptr을 사용하기위한 코드 샘플을 제공해 주실 수 있습니까? (저는 C++을 매우 새로 도입했습니다.) – Aly
@Aly : 당신을 올바르게 이해할 수 있다면 설명 된대로 '벡터'에 할당 할 수 있습니다. –
힙을 사용하지 않음으로써 문제를 해결할 수 있습니다. – tp1
일반 규칙 : 각각의 'new'에 정확히 하나의'delete', 각'new []'에 대해 정확히 하나의'delete []'. –
또는 더 나은 아직은 ... 스마트 포인터에 할당 된 새로운 모든 호출과 삭제할 명시 적 호출이 없습니다! ;) –