힙에 객체가 생성되는 것을 방지하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/10985

  •  08-06-2019
  •  | 
  •  

문제

플랫폼 독립적인 C++ 코드에서 객체가 힙에 생성되는 것을 방지하는 방법을 아는 사람이 있습니까?즉, "Foo" 클래스의 경우 사용자가 다음을 수행하는 것을 방지하고 싶습니다.

Foo *ptr = new Foo;

다음 작업만 허용합니다.

Foo myfooObject;

누구든지 어떤 아이디어가 있습니까?

건배,

도움이 되었습니까?

해결책

닉의 대답 좋은 출발점이지만 실제로 과부하가 필요하므로 불완전합니다.

private:
    void* operator new(size_t);          // standard new
    void* operator new(size_t, void*);   // placement new
    void* operator new[](size_t);        // array new
    void* operator new[](size_t, void*); // placement array new

(좋은 코딩 방법에서는 delete 및 delete[] 연산자도 오버로드해야 한다고 제안합니다. 그렇게 하고 싶지만 호출되지 않으므로 그렇지 않습니다. 정말 필요한.)

파울두 Foo에서 상속된 상태에서는 유지되지만 Foo에서 집계된 상태에서는 유지되지 않는다는 것도 맞습니다.이를 방지하기 위해 몇 가지 템플릿 메타 프로그래밍 마법을 사용할 수 있지만 "사악한 사용자"의 영향을 받지 않으므로 복잡해질 가치가 없을 것입니다.어떻게 사용해야 하는지에 대한 문서화와 올바르게 사용되었는지 확인하기 위한 코드 검토가 유일한 100% 방법입니다.

다른 팁

Foo에 대해 new를 오버로드하여 비공개로 만들 수 있습니다.이것은 컴파일러가 신음한다는 것을 의미합니다 ...Foo 내에서 힙에 Foo 인스턴스를 생성하지 않는 한.이 경우를 포착하려면 Foo의 새 메서드를 작성하지 않으면 링커가 정의되지 않은 기호에 대해 불평하게 됩니다.

class Foo {
private:
  void* operator new(size_t size);
};

추신.예, 쉽게 우회할 수 있다는 것을 알고 있습니다.정말 추천하는 것이 아닙니다. 제 생각에는 나쁜 생각인 것 같습니다. 저는 단지 질문에 대답했을 뿐입니다!;-)

안정적이고 이식 가능한 방식으로 수행하는 방법을 모르겠습니다.하지만..

객체가 스택에 있으면 생성자 내에서 'this' 값이 항상 스택 포인터에 가깝다고 주장할 수 있습니다.이 경우 개체가 스택에 있을 가능성이 높습니다.

모든 플랫폼이 동일한 방향으로 스택을 구현하는 것은 아니라고 생각하므로 앱이 스택이 어느 방향으로 성장하는지 확인하기 시작할 때 일회성 테스트를 수행하는 것이 좋습니다.아니면 퍼지를 해보세요:

FooClass::FooClass() {
    char dummy;
    ptrdiff_t displacement = &dummy - reinterpret_cast<char*>(this);
    if (displacement > 10000 || displacement < -10000) {
        throw "Not on the stack - maybe..";
    }
}

@건강 상태

Foo에서 파생되거나 Foo를 집계하는 클래스를 생성하면 이 문제를 피할 수 있습니다.나는 내가 제안한 것이 (강력하지는 않지만) 파생 클래스와 집계 클래스에 여전히 작동할 것이라고 생각합니다.

예:

struct MyStruct {
    Foo m_foo;
};

MyStruct* p = new MyStruct();

여기에서는 Foo의 숨겨진 new 연산자를 우회하여 힙에 'Foo' 인스턴스를 만들었습니다.

디버그 헤더는 연산자의 새 서명을 재정의할 수 있으므로 ...을 사용하는 것이 가장 좋습니다.완전한 해결책으로서의 서명:

private:
void* operator new(size_t, ...) = delete;
void* operator new[](size_t, ...) = delete;

Foo 클래스 내에 "operator new"라는 함수를 선언하면 일반적인 형태의 new에 대한 액세스를 차단할 수 있습니다.

이것이 당신이 원하는 행동입니까?

이를 인터페이스로 선언하고 자신의 코드에서 구현 클래스를 보다 직접적으로 제어할 수 있습니다.

이는 생성자를 비공개로 만들고 정적 멤버를 제공하여 스택에 객체를 생성함으로써 방지할 수 있습니다.

Class Foo
{
    private:
        Foo();
        Foo(Foo& );
    public:
        static Foo GenerateInstance() { 
            Foo a ; return a; 
        }
}

이렇게 하면 항상 스택에 객체가 생성됩니다.

이것이 컴파일 타임 기회를 제공하는지 확실하지 않지만 클래스에 대한 'new' 연산자 오버로드를 살펴보셨습니까?

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