2008-09-07 7 views
18

그래서 포인터 배열에 대한 포인터가 있습니다. 내가 이것을 다음과 같이 삭제하면 :C++ 포인터에 대한 포인터 삭제

delete [] PointerToPointers; 

포인터도 모두 가리 킵니까? 그렇지 않다면 모든 포인터를 반복하고 삭제해야합니까? 아니면 더 쉬운 방법이 있습니까? 내 google-fu는 나에게이 질문에 대한 좋은 답변을 제공하지 않습니다.

답변

26

예, 개별적으로 삭제하면서 포인터를 반복해야합니다.

이유 : 다른 코드에 배열의 객체에 대한 포인터가 있다면 어떻게 될까요? C++ 컴파일러는 그것이 사실인지 아닌지를 알지 못하므로 명시 적이어야합니다.

"쉬운 방법"으로 두 가지 제안 : (1)이 목적을 위해 서브 루틴을 만드십시오. 적어도 두 번 이상 코드를 작성하지 않아도됩니다. (2) 참조 카운터를 사용하여 객체 배열을 보관하는 "스마트 포인터"디자인 패러다임을 사용하면 객체가 더 이상 코드에서 참조되지 않을 때 객체가 삭제됩니다.

1

을 난 당신이 내가 이상 반복해야 할 것 같아요 (그리고 그래, 난.이 그 중 하나입니다 학교에서 유형 지정 "++ C에 따라 잡기". 벡터를 사용할 필요가 알고있다) 두려워.

3

포인터는 거의 메모리 참조이며 자기 청소가 적은 .net 개체는 아닙니다. 각 클래스에 대해 적절한 소멸자를 만들면 코드 전체에서 대규모 루프보다 삭제가 조금 더 명확 해집니다.

16

제이슨 코헨 (Jason Cohen)에 동의합니다. 루프를 사용하여 포인터를 삭제해야하는 이유가 조금 더 명확해질 수 있습니다. "새"또는 ​​동적 메모리 할당마다 "삭제"메모리 할당 해제가 필요합니다. 때때로 "삭제"는 smartpointers와 같이 숨길 수 있지만 여전히 남아 있습니다.

int main() 
{ 
    int *pI = new int; 
    int *pArr = new int[10]; 

코드에서 우리는 두 개의 동적 메모리 청크를 할당했습니다. 첫 번째는 일반적인 int이며 두 번째는 int 배열입니다.

delete pI; 
    delete [] pArr; 

이 삭제 문

코드의이 비트는 이전 할당을 모두하고있다

int ppArr = new int *[10]; 

    for(int indx = 0; indx < 10; ++indx) 
    { 
    ppArr[indx] = new int; 
    } 

"새로운"의에 의해 할당 된 메모리를 해제합니다. 먼저 동적 배열에서 int의 공간을 만듭니다. 그런 다음 배열의 각 지점에 대해 루프를 수행하고 int를 할당해야합니다.

for(int indx = 0; indx < 10; ++indx) 
    { 
    delete ppArr[indx]; 
    } 
    delete [] ppArr; 

이 메모리를 할당 한 순서와 반대 순서로 할당을 해제 한 순서에 유의하십시오. 왜냐하면 우리가 delete [] ppArr; 먼저 다른 포인터가 무엇인지 알려주는 배열을 잃을 것입니다. 그 덩어리 또는 메모리는 시스템에 다시 주어 지므로 더 이상 신뢰할 수있게 읽을 수 없습니다.

int a=0; 
    int b=1; 
    int c=2; 

    ppArr = new int *[3]; 

    ppArr[0] = &a; 
    ppArr[1] = &b; 
    ppArr[2] = &c; 

이렇게 생각해야합니다. 포인터로 작업한다고해서 포인터가 가리키는 메모리가 동적으로 할당되었음을 의미하지는 않습니다. 즉 포인터가 있다고해서 반드시 삭제해야한다는 의미는 아닙니다. 여기서 생성 한 배열은 동적으로 할당되지만 포인터는 int의 로컬 인스턴스를 가리 킵니다. 이것을 삭제하면 배열 만 삭제하면됩니다.마지막 동적으로 할당 된 메모리에

delete [] ppArr; 

    return 0; 

} 

은 까다로울 수 어쨌든 당신은 안전하게 스마트 포인터처럼 또는 당신의 인생이 훨씬 더 쾌적한 수 있습니다보다는 자신의 STL 컨테이너를 사용하여 마무리 할 수 ​​있습니다.

4

일반 STL 컨테이너와 매우 유사한 구문을 유지하면서 포함 된 포인터를 자동으로 삭제하는 컨테이너의 경우 boost pointer container을 참조하십시오.

+0

니스, 나는 그것에 대해 몰랐습니다! – Frank

0

나는 이것이 왜 그렇게 혼란스럽게 대답했는지 모른다.

포인터의 배열을 삭제하면 일반적으로 int 배열에 사용되는 메모리가 해제됩니다.
개체에 대한 포인터는 주소를 포함하는 정수입니다.

여러 개의 주소는 삭제했지만 개체는 삭제하지 않았습니다.

delete는 메모리 공간의 내용에 대해 신경 쓰지 않으며, 은 소멸자 (s)를 호출하고 mem를 free로 표시합니다.

그냥 개체의 주소의 무리를 삭제 상관 없어, 그것은 단순히 ints를 본다.

그래서 배열을 처음부터 살펴 봐야합니다! 모든 요소에 대해 을 삭제하면 배열 자체의 저장소를 삭제할 수 있습니다. 내 대답은 ... 다소 오래 가지고 지금

음 .... 이상한 ...)

편집 : 제이슨의 대답은 잘못되지 않습니다, 그것은 단지 지점을 타격하는 데 실패합니다. 컴파일러도 c (++)의 다른 항목도 다른 곳의 물건을 삭제하는 것에 신경을 쓰지 않습니다. . 당신은 그것을 할 수 있습니다. 삭제 된 오브젝트 을 사용하려고하는 다른 프로그램 부분은 사용자에게 segfault를 발생시킵니다. 그러나 아무도 당신을 방해하지 않을 것입니다. 개체가 다른 곳에서 참조 될 때 개체에 대한 포인터 배열을 파괴하는 것도 문제가되지 않습니다. 즉 '아무튼

class Street 
{ 
    public: 
     Street(); 
     ~Street(); 
    private: 
     int HouseNumbers_[]; 
} 

typedef *Street StreetSign; 

당신이 거리 표지판의 배열을 가지고, 당신은 streetsigns의 배열을 삭제하면 :

+0

"삭제 된 개체를 사용하려고하는 다른 프로그램 부분은 사용자에게 segfault가됩니다.".... segfaulting이 아마도 가장 좋은 결과 일 수 있으며 문제가있는 부분을 트래핑 할 수 있습니다.그러나 다른 가능성은 많이 있습니다. 예를 들어 파일 쓰기 버퍼가 현재 사용 가능한 메모리에 할당 된 경우 나중에 종료 될 때까지 손상되지 않도록 할 수 있습니다. –

3

이 같은 클래스를하였습니다의이 (pseudocoded)를 가지고 실제 예를 .Imagine하자 자동으로 sreets를 삭제한다는 의미입니다. 그들은 여전히 ​​벽돌과 박격포에 있습니다. 더 이상 그 징조를 가리 키지 않습니다. 너는 그 특정 거리에 포인터의 경우를 제거했다.

포인터의 배열은 개념적으로 정수 배열과 비슷하지만 다양한 개체의 메모리 위치를 나타내는 숫자 배열입니다. 그것은 사물 자체가 아닙니다.

[] 포인터의 배열을 삭제하면 정수 배열이 삭제됩니다.

관련 문제