2011-11-27 5 views
1

메모리의 뾰족한 객체를 건드리지 않고 포인터 배열을 삭제하는 방법이 있는지 알고 싶습니다.메모리의 뾰족한 객체를 삭제하지 않고 포인터 배열을 삭제 하시겠습니까?

나는 이틀 전에 구현 된 HashSet에 대한 제한 루틴을 작성하므로 해시 테이블이 가득 차면 다른 두 배 크기의 테이블로 바뀝니다. 개체 (User)에 대한 포인터 배열을 사용하여 해시 테이블을 나타내고 있는데 배열 자체는 내 HashSet 클래스에서 동적으로 선언되므로 해시 함수를 사용하여 모든 내용을 새 테이블에 복사 한 후에 삭제할 수 있습니다.

  1. 원래 배열 크기의 두 배에 해당 크기로 다른 테이블을 선언 :

    그래서 기본적으로 내가 할 필요가있다.

  2. 내 원래 배열의 User 개체에 대한 모든 포인터를 내 해시 함수를 적용하는 새로운 개체로 복사합니다.이 개체는 메모리에서 User 개체를 가져오고 사용자 이름을 나타내는 문자열을 사용하여 색인을 계산합니다.
  3. 원본 배열의 모든 포인터를 새 배열에 삽입 한 후 원래 배열에 할당 된 메모리를 확보하고 HashSet 클래스 (구성원 전용 userContainer)의 포인터를 새 배열의 위치로 바꿔야합니다 정렬).

문제는 내가 그것을 위해 할당 된 메모리를 해제 delete[] userContainer를 사용하는 경우 새로 만든 대체 배열이 메모리에서 해제 위치를 가리 있도록, 또한 메모리에있는 모든 개체를 삭제할 것입니다!

+0

프로그래밍 언어에 대해 언급하지 않으려 고 죄송합니다. It is C++ –

답변

4

당신이 묘사 한 것이 올바르게 들리지 않습니다.그런 다음 그것을 채우기

A** array1 = new A*[32]; 

:
의 당신이 class A이 있고와 A의 배열을 만들라고하자 delete[] array1array1의 요소를 해제하지 않습니다 이렇게

for(int i = 0; i < 32; ++i) 
    array1[i] = new A(); 

.

그래서이 안전 :

A** array1 = new A*[32]; 
for(int i = 0; i < 32; ++i) 
    array1[i] = new A(); 

A** arary2 = new A*[64]; 
for(i = 0; i < 32; ++i) 
    array2[i] = array1[i]; 

delete [] array1; 

for(i = 0; i < 32; ++i) 
    // do something with array2[i] 
+0

환상적입니다, 지금 할 수 있습니다 : array1 = array2, 그래서 내 클래스 멤버는 메모리의 유효한 배열을 가리 킵니까? –

+1

네,'delete [] array1'을 호출 한 후에'array1 = array2'를 설정할 수 있습니다. 다시 끝날 때까지 완료됩니다! – esskar

2

일반적으로 포인터 배열을 삭제하면 포인터가 가리키는 개체가 존재합니다. 사실, 이것은 큰 메모리 누출의 잠재적 인 원인입니다.

그러나 참조 일괄 계산 환경 (예 : Objective-C 또는 Qt)에서 배열 OBJECT (단순한 대 [] 배열)를 삭제하면 참조 횟수가 감소하고 개체가 삭제됩니다. 카운트가 0이됩니다.

그러나 해시 테이블을 재구성하는 경우 배열을 삭제하기 전에 포인터 값을 저장하는 것이 좋습니다. 그렇지 않으면 주소가 지정된 모든 개체가 손실됩니다. 저장하면 참조 카운트를 증가시킬 수 있습니다 (올바른 경우).

(그것은 당신이 상대하고 어떤 언어를 알고 도움이 될 것이다, 당신은 "배열"무슨 뜻.)

+0

프로그래밍 언어를 언급하지 않아서 죄송합니다. 그것은 C++입니다 –

1

당신이 malloc/free의 차이를 아십니까, new/deletenew[]/delete[]를? 소멸자를 호출하지 않기를 원한다면, 상황에 따라 new[]/delete[]을 사용하지 않을 수도 있습니다.

+0

원래 배열에 할당 된 공간을 확보하고 난 여전히 교체 배열에 그들을 얻기 위해 필요한 포인터를 삽입 했으므로 여전히 메모리에있는 개체가 있습니다. 그리고 malloc/free, new/delete와 malloc/free, new []/delete [] 사이의 차이는 모르지만 새로운/delete와 new []/delete []는 malloc/free를 기반으로합니다. 내 목표에 도달하려면 malloc/free를 사용해야 할 수도 있습니다. –

2

나는 당신의 문제가 있는지 생각하지 않습니다. 당신 주위에 자유롭게만큼 당신이 원하는대로 포인터를 복사 할 수 있습니다

Foo * brr[10]; 

{ 
    Foo * arr[10]; 

    // This is not touching the objects! 
    for (Foo * it = arr; it != arr + 10; ++it) *it = new Foo; 

    std::copy(arr, arr + 10, brr); 

} // no more arr 

for (Foo * it = brr; it != brr + 10; ++it) delete *it; // fine 

: 다음은 걱정할 필요가 없다는 것을 보여주기 위해 아기 예입니다. 포인터가 더 이상 필요하지 않을 때을 가리키는 개체를 삭제해야합니다.

아마도 사소한 알림 : 포인터에는 소멸자가 없습니다. 특히 포인터가 범위를 벗어날 때 아무 것도 발생하지 않습니다..

+0

'arr'이 죽는 것을 아주 쉽게 알아챌 수 있습니다. ;) – Xeo

+0

@ o : 척! –

관련 문제