문제

나는 이와 같이 정의 된 수업 인 수업을 보았다 ..

class StringChild : public StringBase
    {
public:
    //some non-virtual functions
    static StringChild* CreateMe(int size);
private:
    unsigned char iBuf[1];
    };

정적 공장 기능에는 다음과 같은 구현이 있습니다.

return new(malloc(__builtin_offsetof(StringChild ,iBuf[size]))) StringChild();

내가 이해하는 한,이 기능은이 클래스를 확장하기 위해 새로운 배치를 사용하고 있습니다.

회원이 1 명 밖에없고 힙에 할당 되었기 때문에 안전합니까?

도움이 되었습니까?

해결책

일반 C에서 가변 길이 배열의 비를 불러 일으키는 데 사용되는 오래된 C 트릭입니다. 예, 적절한 할당기구를 사용하는 한 C ++에서도 작동합니다 (원하는 크기의 원시 메모리를 할당하는 것과 같이 원하는 크기와 원하는 크기를 할당합니다. 그런 다음 거기에 물체를 새롭게 배치하십시오). 할당 된 메모리의 끝을 방황하지 않는 한 안전하지만 적어도 일부 메모리 디버거를 혼동하는 경향이 있습니다.

이 기술을 사용할 때 절대적으로 확신 해야하는 한 가지는 변수 길이 배열이 객체 레이아웃의 마지막 요소라는 것입니다. 그렇지 않으면 다른 내부 변수를 걸어 갈 수 있습니다.

그러나 공장 기능의 구현에 대해 조금 모호합니다. '크기'매개 변수가 실제로 원하는 배열 크기라고 가정합니까? 또한 후자가 대부분의 경우 작동 할 수 있지만 '삭제'가 아닌 '무료'를 사용하여 위의 메모리를 해제해야한다는 것을 잊지 마십시오.

메모리가 왜 이런 식으로 관리되어야하는지에 대한 강력한 이유가 없다면 배열을 std :: 벡터로 교체합니다.

다른 팁

IBUF가 구조의 마지막 멤버 인 경우 포드에 대해서는 괜찮습니다. 비 POD와 관련된 문제는 예를 들어일 수 있습니다. 컴파일러는 공개/개인/보호 회원을 자유롭게 지시 할 수 있으며, 가상 기본 클래스는 가장 파생 된 Object IIUC 등의 끝에 있습니다.

귀하의 구조는 비 POD (기본 클래스가 있음)이므로 권장하지 않습니다.

또한 이와 같은 인스턴스를 만드는 경우

return new(malloc(__builtin_offsetof(StringChild ,iBuf[size]))) StringChild();

Malloc이 획득 한 메모리가 무료로 해제되어야하는지 확인해야하므로 다음과 같은 인스턴스를 삭제하십시오.

obj->~StringChild();
free(obj);

아마 당신은 사용하고 싶을 수도 있습니다 ::operator new() 할당을 위해

엄격하게 말하면, 그 이후로 StringChild 파생됩니다 StringBase 안전하지 않습니다. C ++ 표준은 기본 클래스 서브 버젝트의 레이아웃을 지정하지 않습니다. 10 항 3 항 :

기본 클래스 하위 객체가 가장 파생 된 객체 (1.8)에 할당되는 순서는 지정되지 않습니다.

만약에 StringChild 포드 구조물이었고 그러한 기술은 안전 할 것입니다.

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