문제

이것은 한동안 나를 잔소리하고있는 질문입니다. 나는 항상 C ++가 "삭제"연산자 (브래킷없이)가 "new []연산자와도 작동하도록 설계되어야한다고 생각했습니다.

내 생각에, 이것을 쓰십시오 :

int* p = new int;

1 요소 배열을 할당하는 것과 동일해야합니다.

int* p = new int[1];

이것이 사실이라면, "삭제"연산자는 항상 배열을 삭제할 수 있으며 "delete []연산자가 필요하지 않습니다.

"delete []연산자가 C ++에 도입 된 이유가 있습니까? 내가 생각할 수있는 유일한 이유는 배정 배열에 작은 메모리 풋 프린트 (어딘가에 배열 크기를 저장해야 함)가 있으므로 "삭제"vs "delete []를 구별하는 작은 메모리 최적화였습니다.

도움이 되었습니까?

해결책

개별 요소의 소멸자가 호출됩니다. 예, 포드 어레이의 경우 차이가 크지 않지만 C ++에는 사소한 파괴자가있는 객체의 배열을 가질 수 있습니다.

자, 당신의 질문은 왜 그렇게하지 않는지입니다 new 그리고 delete 처럼 행동합니다 new[] 그리고 delete[] 그리고 제거하십시오 new[] 그리고 delete[]? 나는 C ++ 기능을 사용하지 않으면 (적어도 런타임에) 비용을 지불 할 필요가 없다고 말한 Stroustrup의 "Design and Evolution"책으로 돌아갈 것입니다. 지금 서있는 방식, a new 또는 delete 효율적으로 행동 할 것입니다 malloc 그리고 free. 만약에 delete 그랬어 delete[] 즉, James Curran이 지적했듯이 런타임에 약간의 오버 헤드가있을 것입니다.

다른 팁

젠장, 나는 질문의 요점을 놓쳤다. 그러나 나는 원래의 대답을 사이드 노트로 남겨 둘 것이다. 우리가 삭제 한 이유 []는 오래 전에 [CNT]를 삭제했기 때문에 오늘날에도 삭제 [9] 또는 삭제 [CNT]를 삭제하더라도 컴파일러는 [] 사이의 물건을 무시하지만 OK를 컴파일합니다. 그 당시 C ++는 먼저 프론트 엔드로 처리 한 다음 일반 C 컴파일러에 공급되었습니다. 그들은 커튼 아래 어딘가에 수를 저장하는 속임수를 할 수 없었습니다. 아마도 그 당시에는 생각조차 할 수 없었습니다. 그리고 뒤로 호환성을 위해, 컴파일러는 아마도 [] 사이에 주어진 값을 배열로 사용했을 것입니다. 그러한 값이 없다면 접두사에서 수를 얻었으므로 두 방식으로 작동했습니다. 나중에, 우리는 []와 모든 것이 효과가 없었습니다. 오늘날, 나는 "delete []가 필요하다고 생각하지 않지만 구현은 그런 식으로 요구합니다.

내 원래 대답 (요점을 그리워) ::

"삭제"는 단일 객체를 삭제합니다. "delete []는 객체 배열을 삭제합니다. 삭제 []가 작동하려면 구현은 배열의 요소 수를 유지합니다. ASM 코드를 디버깅하여 이것을 다시 확인했습니다. 구현 (vs2005)에서 테스트 한 경우 카운트는 객체 배열에 대한 접두사로 저장되었습니다.

단일 객체에서 "delete []를 사용하는 경우 카운트 변수는 쓰레기이므로 코드가 충돌합니다. 객체 배열에 "삭제"를 사용하는 경우 일부 불일치로 인해 코드가 충돌합니다. 나는 지금이 사건을 테스트했다!

"삭제는 배열에 할당 된 메모리를 삭제합니다." 다른 대답의 진술은 옳지 않습니다. 객체가 클래스 인 경우 삭제는 DTOR를 호출합니다. DTOR 코드를 중단 점 int 만 배치하고 객체를 삭제하면 중단 점이 적용됩니다.

나에게 일어난 것은 컴파일러 및 라이브러리가 "새"에 의해 할당 된 모든 객체가 객체 배열이라고 가정하면 단일 객체 또는 객체 배열에 대해 "삭제"를 호출하는 것이 좋습니다. 단일 객체는 단지 1의 카운트를 가진 객체 배열의 특별한 경우 일 것입니다. 어쨌든 내가 놓친 것이있을 것입니다 ... 어쨌든 ...

다른 모든 사람들이 당신의 질문의 요점을 놓친 것 같습니다. 나는 몇 년 전에 같은 생각을했으며 답을 얻을 수 없었다고 덧붙입니다.

내가 생각할 수있는 유일한 것은 단일 객체를 배열로 취급하기위한 아주 작은 오버 헤드가 있다는 것입니다 (불필요한 것”for(int i=0; i<1; ++i)" )

다른 답변이 없기 때문에 이것을 추가합니다.

정렬 delete[] 포인터 투-베이스 클래스에서 사용할 수 없습니다. 컴파일러는 호출 할 때 객체 수를 저장합니다. new[], 그것은 객체의 유형이나 크기를 저장하지 않습니다 (David가 지적했듯이 C ++에서는 사용하지 않는 기능을 거의 지불하지 않습니다). 그러나 스칼라 delete 기본 클래스를 통해 안전하게 삭제할 수 있으므로 정상적인 물체 정리 및 다형성 정리에 모두 사용됩니다.

struct Base { virtual ~Base(); };
struct Derived : Base { };
int main(){
    Base* b = new Derived;
    delete b; // this is good

    Base* b = new Derived[2];
    delete[] b; // bad! undefined behavior
}

그러나 반대의 경우-비가 적성 소멸자-스칼라 delete 가능한 한 저렴해야합니다. 객체 수를 확인하거나 삭제되는 객체 유형을 확인해서는 안됩니다. 이렇게하면 내장형 유형 또는 일반 데이터 유형에서 삭제가 매우 저렴합니다. 컴파일러가 호출되기 만하면됩니다. ::operator delete 그리고 다른 것은 없습니다 :

int main(){
    int * p = new int;
    delete p; // cheap operation, no dynamic dispatch, no conditional branching
}

메모리 할당에 대한 철저한 처리는 아니지만 이것이 C ++에서 사용 가능한 폭의 폭 넓은 메모리 관리 옵션을 명확히하는 데 도움이되기를 바랍니다.

Marshall Cline에는 일부가 있습니다 이 주제에 대한 정보.

delete [] 각 멤버의 소멸자가 (유형에 적용 가능한 경우) 호출되도록합니다. delete 배열에 할당 된 메모리를 삭제하면됩니다.

다음은 좋은 읽기입니다. http://www.informit.com/guides/content.aspx?g=cplusplus&seqnum=287

그리고 아니요, 배열 크기는 C ++의 어느 곳에도 저장되지 않습니다. (이 진술이 부정확하다는 것을 지적 해 주셔서 감사합니다.)

나는 Aaron의 대답에 약간 혼란스러워서 솔직히 말해서 왜 삭제 []가 필요한 이유와 위치를 완전히 이해하지 못한다는 것을 인정합니다.

나는 그의 샘플 코드로 약간의 실험을했다 (오타 몇 개를 수정 한 후). 내 결과는 다음과 같습니다. 오타 : ~베이스가 기능 본체베이스가 필요했습니다 *B는 두 번 선언되었습니다.

struct Base { virtual ~Base(){ }>; };
struct Derived : Base { };
int main(){
Base* b = new Derived;
delete b; // this is good

<strike>Base</strike> b = new Derived[2];
delete[] b; // bad! undefined behavior
}

편집 및 실행

david@Godel:g++ -o atest atest.cpp 
david@Godel: ./atest 
david@Godel: # No error message

delete []가 제거 된 수정 된 프로그램

struct Base { virtual ~Base(){}; };
struct Derived : Base { };

int main(){
    Base* b = new Derived;
    delete b; // this is good

    b = new Derived[2];
    delete b; // bad! undefined behavior
}

편집 및 실행

david@Godel:g++ -o atest atest.cpp 
david@Godel: ./atest 
atest(30746) malloc: *** error for object 0x1099008c8: pointer being freed was n
ot allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

물론 Delete [] b가 실제로 첫 번째 예에서 작동하는지 모르겠습니다. 컴파일러 오류 메시지를 제공하지 않는다는 것을 알고 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top