>백엔드 개발 >C++ >C에서 기본 포인터 정의되지 않은 동작을 통해 파생 배열을 삭제하는 이유는 무엇입니까?

C에서 기본 포인터 정의되지 않은 동작을 통해 파생 배열을 삭제하는 이유는 무엇입니까?

Barbara Streisand
Barbara Streisand원래의
2024-10-31 16:54:02551검색

Why is Deleting a Derived Array via a Base Pointer Undefined Behavior in C  ?

정의되지 않은 동작이 있는 이유: 기본 포인터를 통해 파생된 배열 삭제

C 03 표준에서는 기본 포인터를 통해 파생 개체의 배열을 삭제하도록 지정합니다. 정의되지 않은 동작입니다. 이는 삭제할 개체의 정적 유형과 동적 유형의 차이 때문입니다.

정적 유형과 동적 유형

포인터의 정적 유형은 코드에 선언된 유형이고 동적 유형은 가리키는 객체의 실제 유형입니다. 예제 코드에서:

<code class="cpp">struct B { virtual ~B() {} };
struct D : B {};

B* p = new D[20];</code>

p의 정적 유형은 B*이고, *p의 동적 유형은 D입니다.

정의되지 않은 동작

표준에서는 두 번째 대안(배열 삭제)에서 동적 유형이 정적 유형과 다른 경우 동작이 정의되지 않는다고 명시합니다. 이는 p가 D 요소 배열의 시작 부분을 가리키지 않기 때문입니다. 이는 첫 번째 요소의 B 하위 개체를 가리킵니다. 따라서 delete [] p;로 삭제합니다. 유효하지 않습니다.

구현 고려 사항

구현 시 이 규칙을 적용하려면 컴파일러가 배열의 동적 유형을 결정한 다음 p를 해당 유형으로 동적으로 캐스팅해야 합니다. 삭제하기 전에. 그러나 이는 다형성을 사용하지 않는 경우 불필요한 오버헤드를 발생시킵니다.

다형성 배열

다형성 동작을 포함하는 배열이 필요한 경우 다음을 생성할 수 있습니다. C의 기존 기능을 사용하여 자체 구현. 예를 들어 파생 객체에 대한 포인터 배열을 래핑하는 클래스 템플릿을 만들 수 있습니다.

<code class="cpp">template <typename T>
class PolymorphicArray {
public:
    PolymorphicArray(size_t size) : _size(size), _data(new T*[_size]) {}
    ~PolymorphicArray() { delete[] _data; }
    T*& operator[](size_t index) { return _data[index]; }

private:
    size_t _size;
    T** _data;
};</code>

이 클래스를 사용하면 표준을 위반하지 않고 파생 객체 배열에 다형성 동작을 사용할 수 있습니다.

위 내용은 C에서 기본 포인터 정의되지 않은 동작을 통해 파생 배열을 삭제하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.