2013-08-18 3 views
0

좋아, 내가 정의 new 연산자와 힙 개체를 만들려면, 나는이 같은 new 연산자 오버로드해야한다는 것을 알고 : 내가 사용 힙 개체를 만들려면, 다음사용자 지정 할당 연산자를 사용하여 STACK 개체를 만들 수 있습니까?

void* operator new(size_t size, int unused) 
{ 
    void* ptr = malloc(size); 
    //some custom code 
    return ptr; 
} 

과 이 오버로드 된 연산자는 다음과 같습니다.

SomeClass* a = new(0) SomeClass; 

질문 : 스택 객체를 만들려면 어떻게해야합니까?

+3

정상적인 스택 변수와 동적으로 스택을 할당하는 것의 차이점은 무엇입니까? (여전히 포인터를 콜렉션에 넣거나 리턴 할 수는 없지만) 시스템은 * may * [alloca'] (http://linux.die.net/man/3/alloca) 함수가 있어야합니다. –

+2

오와'alloca' 함수에 대한 경고는 할당해야하는 스택을 가진 함수에서 사용해야하기 때문에 연산자에서 실제로 사용할 수 없습니다. –

+0

@JoachimPileborg 문제는, 나는 새로운 연산자를 오버라이드하여 모든 할당 된 객체를 기록해야하는 간단한 메모리 관리자를 작성하고있다. 재정의 된 new 연산자는 할당 된 블록에 대한 정보를 맵 <>에 추가해야하지만 맵 <>에 삽입 될 쌍 <>을 생성하면 실제로이 새 연산자가 호출되고 스택 오버플로가 발생할 때까지 반복됩니다. 힙에 다른 객체를 할당하는 것은 새로운 것에서는 불가능한 것 같습니다. 내가 말하는 것에 대해 알고 있다면 overriden new 연산자를 사용하지 않고이 맵에 대해 <> 쌍을 만들고 싶습니다. – Aikei

답변

2

아마도이 답변은 필요하지 않을 수도 있지만 할 수 있습니다. 아래 예제 코드를 참조하십시오. 메모리를 미리 할당하고 새로운 배치에 전달하십시오. 배열 new [] form을 사용하는 경우 다음과 같이 할 수 있습니다.

void * rawMemory = operator new [] (25 * sizeof (std :: stack));

리소스를 관리하는 팩토리 메서드가있는 스택의 배열이 있거나 뭔가가 있으면. 어느 쪽이든 귀하의 응용 프로그램과 사용 사례에 따라 다릅니다. 다음은 간단한 예를 들어 당신이 25 가지 스택을 관리하고 고객에게 전달 될 수있다 더 유용 할 것 같습니다 배열 버전을 사용

#include <iostream> 
#include <stack> 

int main (int argc, char *argv[]) 
{ 
    void *rawMemory = operator new(sizeof(std::stack<unsigned int>)); 
    std::stack<unsigned int> *s = new (rawMemory) std::stack<unsigned int>; 

    s->push(10); 

    std::cout << s->top() << std::endl; 

    return 0; 
} 

두 번째 예를 보여줍니다. 또한 귀하의 의견에 답하십시오. 이번에는 스택 정의에 컨테이너가 정의되어 있는지 확인하십시오.이 경우 컨테이너에 벡터를 사용하고 있습니다. 스택 컨테이너이지만 기본적으로는

#include <iostream> 
#include <stack> 
#include <vector> 

int main (int argc, char *argv[]) 
{ 
    typedef std::stack<unsigned int,std::vector<unsigned int> > StackType; 

    void *rawMemory = operator new[](25*sizeof(StackType)); 

    StackType *stacks = static_cast<StackType*> (rawMemory); 

    // allocate 
    for (unsigned int i = 0; i < 25; ++i) 
    { 
    new (stacks+i) StackType; 
    } 

    stacks[1].push(10); 
    std::cout << stacks[1].top() << std::endl; 

    // don't forget to delete or smart resize 
    for (int i = 24; i >= 0; --i) 
    { 
    StackType x; 
    std::swap (x, stacks[i]); 
    } 

    return 0; 
} 
+1

글쎄, std :: stack 그냥 컨테이너가 아닌가요? 실제로 스택 객체가 할당 된 스택과 관련이 있습니까? – Aikei

+0

위의 내 의견을 참조하십시오. Stack은 컨테이너이지만 기본 컨테이너가 deque로 기본 설정되어 있습니다. – bjackfly

1

당신은이 같은 매크로를 정의 할 수 있습니다 양단 할 수있는 기본 컨테이너가 있습니다 배치 새로운 사용

#define STACK_NEW(T) new (alloca(sizeof(T))) T 

alloca()상의 블록을 할당하기를 스택하고 그 위에 T 유형의 오브젝트를 구성하십시오. 다음과 같은 방법으로이 매크로를 사용하십시오

#define STACK_NEW_ARRAY(T, n) new (alloca(n * sizeof(T))) T 

:

q->~MyObj(); 

삭제 :

int * p = STACK_NEW(int); 
MyObj * q = STACK_NEW(MyObj) (my, constructor, parameters); 
int * r = STACK_NEW_ARRAY(int, 42); 

당신은 수동으로 개체를 파괴해야합니다 당신은 또한 배열 버전을 정의 할 수 있습니다 그들에게는 정의되지 않은 행동이있을 것이다.

경고 :이 모든 시설은 매우 안전하지 않습니다. 코드베이스에 체계적으로 위험한 도구를 사용하지 말 것을 강력히 권합니다. 내가 볼 수있는 한 안전하게 사용하는 방법은 없으며 으로 통증을 유발합니다!

관련 문제