2012-11-02 6 views
1

동적으로 함수의 배열에 메모리를 할당하고 있습니다. 내 질문은 : 일단 함수가 실행을 마친 메모리가 해제됩니다?동적 배열이 범위를 벗어날 때 메모리가 해제됩니까

코드 :

void f(){ 
    cv::Mat* arr = new cv::Mat[1]; 
    ... 
} 
+0

힙을 사용하지 않음으로써 문제를 해결할 수 있습니다. – tp1

+2

일반 규칙 : 각각의 'new'에 정확히 하나의'delete', 각'new []'에 대해 정확히 하나의'delete []'. –

+2

또는 더 나은 아직은 ... 스마트 포인터에 할당 된 새로운 모든 호출과 삭제할 명시 적 호출이 없습니다! ;) –

답변

3

아니, 아니다 (그런 이유로, 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 
    ... 
} 
+0

그러나 배열의 크기를 동적으로 조정할 수도 없습니다 (적어도 C++ 표준에서는 gcc가 동적 크기 배열을 확장으로 제공한다는 것을 알고 있습니다). –

+0

@ slavik262 감사합니다. 나는 'vector'라는 예제를 추가했다. OP의 예제는 컴파일 시간 상수 '1'을 사용하지만. – juanchopanza

1

아니, 물론 아니지.

new마다 정확히 delete이 필요합니다.

new[]마다 정확히 delete[]이 필요합니다.

일치하는 숫자가 delete[]이 아니므로 프로그램이 손상되었습니다.

+0

이상한 downvote ... – juanchopanza

+1

"그 이유로 성인 C++을 사용하는 방법은 새로운 포인터 나 포인터를 사용하지 않는 것입니다. 그런 다음에는 문제가 없습니다. " 뭐? 힙을 사용하지 않을 것을 제안합니까? –

+0

@ slavik262 : 물론 아닙니다. 하지만 나는 수동으로 힙 **을 사용하지 않기를 강력하게 권합니다 **! 라이브러리 기능이 더 우수하고 안전합니다. –

1

번호 배열은 힙에 할당이 범위를 벗어나하기 전에, 당신은 그것을 삭제해야합니다 :

void f() { 

    cv::Mat * arr = new cv::Mat[1]; 

    // ... 

    delete [] arr; 

} 
+0

새로운 C++ 코드는 명시 적으로'delete' 사용을 피하려고 노력해야합니다 -'unique_ptr'과'shared_ptr'은 자동으로 그것을 수행하고보다 나은 소유권 의미를 제공합니다. –

5

아니요, new을 사용하여 할당 된 메모리는 포인터가 범위를 벗어날 때 자동으로 해제되지 않습니다. 이 범위를 벗어나면

그러나, 당신은 (그리고 한다) 메모리를 해제 핸들을 C++ (11)의 unique_ptr을 사용할 수 있습니다

void f(){ 
    std::unique_ptr<cv::Mat[]> arr(new cv::Mat[1]); 
    ... 
} 

C++ (11)는 포인터에 대한 shared_ptr 제공하면 복사하고 싶을 수도 있습니다. 현대의 C++은 성능에 거의 영향을 미치지 않고 안전한 메모리 관리를 제공하므로 이러한 "스마트 포인터"를 사용하도록 노력해야합니다.

+0

아니 C++ 11 for me :(gcc를 설치했는데 apt-get을 사용하여 최신의 멋진 것을 제공 하겠지만 unique_ptr은 존재하지 않습니다. – Aly

+2

@Aly,'g ++'를 호출 할 때' g ++ -std = C++ 11' 또는'g ++ -std = C++ 0x'.이 중 하나가 'unique_ptr'을 활성화해야합니다 .. –

4

아니요. new에 대한 모든 전화는 delete에 대한 전화와 일치해야합니다.

귀하의 경우 arriteself은 자동 저장 기간이있는 변수입니다. 즉, 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; 

각 값 초기화 될 것입니다 경우에 얻을 - 이동에서 vectorN에 항목을 만들 수 있습니다

또는 다양한 알고리즘을 사용하여 벡터로 요소를 채울 수 있습니다. 그러한 예로는 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; 
+0

안녕하세요, 무작위 방식으로 배열에 할당하기 때문에 벡터를 사용하지 않습니다. . 배열 5 크기 경우 arr [3] arr [1] 등 벡터 함께 시도 할 때 그냥 예외없이 프로그램을 종료 할 설정할 수 있습니다. (.C++ 11 std :: auto_ptr을 사용하기위한 코드 샘플을 제공해 주실 수 있습니까? (저는 C++을 매우 새로 도입했습니다.) – Aly

+1

@Aly : 당신을 올바르게 이해할 수 있다면 설명 된대로 '벡터'에 할당 할 수 있습니다. –