2009-02-24 14 views
19

내 프로그램에서 약간의 메모리 누수 찾기를하고 있지만 내 방식으로 새로 작성 및 삭제 (새 항목 [] 및 삭제 []) 은 아무 것도하지 않는 것 같습니다.새로 고침/새로 고침

void* operator new (unsigned int size, const char* filename, int line) 
{ 
    void* ptr = new void[size]; 
    memleakfinder.AddTrack(ptr,size,filename,line); 
    return ptr; 
} 

new에 오버로드 된 방식은 위의 코드 조각에 나와 있습니다. 나는 void *를 반환하는 연산자로 뭔가를 추측하지만, 그것에 대해 어떻게 해야할지 모르겠습니다.

+6

"아무 것도하지 않는 것 같습니다": 무엇을 의미합니까? 연산자를 오버로드했지만 기본 연산자 new를 오버라이드 *하지 않았으므로 "new x"는 기본 new를 호출하고 "new (filename, line) x"는 오버로드 된 버전을 호출합니다. –

답변

11
void* ptr = new void[size]; 

할 수 없습니다. 고쳐.

절대 전역 적으로 새로운/과부하를 시도하지 마십시오. 클래스를 기본 클래스에 포함하고이 클래스에서 모든 객체를 파생 시키거나 네임 스페이스 또는 템플릿 할당 자 매개 변수를 사용하십시오. 왜, 너는 물을지도 모른다. 왜냐하면 당신의 프로그램이 하나의 파일 이상이고 STL이나 다른 라이브러리를 사용하기 때문에 당신은 망칠 것입니다.

void * operator new(size_t size) _THROW1(_STD bad_alloc) 
{  // try to allocate size bytes 
    void *p; 
    while ((p = malloc(size)) == 0) 
    if (_callnewh(size) == 0) 
    {  // report no memory 
     static const std::bad_alloc nomem; 
     _RAISE(nomem); 
    } 

    return (p); 
} 
+3

사실, 나는 그 일을할만한 이유가있었습니다.우리는 DLL 경계를 넘어 안전하지 않은 방식으로 힙을 사용하는 컴파일러 "문제"를 가지고있었습니다. 수정 프로그램은 특정 명명 된 힙을 사용하는 "새로운"사용자 지정 버전을 만드는 것이 었습니다. –

+0

왜 당신은 버그를 제기하지 않고 화재로 게임을 선택 했습니까? – dirkgently

+0

우리가했습니다. 우리가 얻은 응답은 "DLL이 시스템에서 잘 처리되지 않습니다"라는 라인을 따라 뭔가있었습니다. 우리는 결국 그것들을 사용하지 않았지만, 단기적으로 이것은 문제를 해결했습니다. –

4

오버로드 된 연산자를 올바르게 호출합니까? 즉, 추가 매개 변수를 전달 하시겠습니까?

4

문제는 당신이 오버로드 된 새 연산자에 추가 한 두 개의 인수 의존 :

여기 VS2005 new.cpp에서 new 운영자의 증류 한 버전입니다. 어떤 식 으로든 filename과 line을 global로 만들거나 new를 오버로딩하고 하나의 클래스를 삭제한다면 멤버 변수를 만들어 보라. 그게 더 잘 작동 할거야.

12

여기서 문제는 새 매개 변수 프로필이 표준 연산자 new와 일치하지 않아서 숨겨진 것이 아니므로 아직 사용중인 것입니다. 대한

귀하의 매개 변수 프로파일 새와 같이 할 필요를 삭제 :

어쩌면
void* operator new(size_t); 
void operator delete(void*, size_t); 
44

당신이 처리기 약간의 마법으로 당신이 원하는 것을 할 수 있습니다

#include <iostream> 

using namespace std; 

void* operator new (size_t size, const char* filename, int line) { 
    void* ptr = new char[size]; 
    cout << "size = " << size << " filename = " << filename << " line = " << line << endl; 
    return ptr; 
} 

#define new new(__FILE__, __LINE__) 

int main() { 
    int* x = new int; 
} 
+12

이것은 굉장합니다. –

+2

'unsigned int' 대신'size_t'가되어야합니까? 나는 이러한 유형이 동등하지 않은 몇몇 플랫폼을 믿습니다. – iggy

+0

왜'void * operator new (size_t size, const char * filename, int line)'의 첫 번째 인수가'size_t'입니까? 'delete' 연산자를 오버라이드하고 싶다면 어떻게해야합니까? – naive231

121

RE :

절대적으로 새로운/과부하를 시도해서는 안됩니다.

누군가가 C++의 덜 일반적인 기능을 사용하려고 시도 할 때마다 왜 누군가가 수행하지 않아야하는 것처럼 행동합니까?

항상 진행되고 있으며, 꽤 일반적이며,이 작업을 수행하지 않은 회사에서 일하지 않았습니다.

세계적으로 새로운 과부하 및 삭제 등 자신의 권리를 염두에

아무도 코드의 수백만 라인 프로그램을 통해 이동하고, 추가 예정되지 않으며, 메모리, 메모리 버그, 버퍼 오버런 추적에 매우 도움이됩니다 새 클래스와 멤버를 각 클래스에 삭제하십시오. 그건 바보 야.

+1

여기에 필요한 것은 * overload *가 아닌 new/delete의 * override *입니다. 필자는 RTOS를 사용하는 임베디드 시스템에서 최근에이 작업을 수행해야했습니다. RTOS가 malloc/free에 대해 스레드 안전 래퍼를 제공했지만이 응용 프로그램은 new/delete를 사용하여 C++로 작성되었습니다. thread-safe malloc/delete를 강제적으로 사용하려면 new/delete를 전역 적으로 오버라이드 (override) 할 필요가있었습니다. 그러나 새로운 [], delete [] 및 new (std :: nothrow) 및 delete (std :: nothrow)도 고려해야합니다. – Clifford

+0

사실 새 매크로를 추상화하고 매크로로 삭제하는 것이 훨씬 더 좋습니다. NEW(), DELETE(). 이것은 스택 프레임을 당기고, 파일과 라인을 기록하고, 미리 정의 된 힙에서부터 할당하고, 새로운 것을 실재로 배치하는 것과 같은 추가 작업을 수행하도록합니다. 오버로딩은 전체 추상화를 통해 달성 할 수있는 모든 범위의 유연성을 가지고 있지 않습니다. – Dan

+1

또한 자신의 OS를 작성하는 것도 좋은 방법입니다. – imallett