문제

저는 구조 크기가 가변 길이 문자열에 따라 달라지는 가변 길이 구조(TAPI)를 사용하는 일부 레거시 C++ 코드를 작업해 왔습니다.구조체는 배열을 캐스팅하여 할당됩니다. new 따라서:

STRUCT* pStruct = (STRUCT*)new BYTE [sizeof(STRUCT) + nPaddingSize];

그러나 나중에 메모리는 다음을 사용하여 해제됩니다. delete 부르다:

delete pStruct;

이 배열의 혼합은 new [] 그리고 비배열 delete 메모리 누수가 발생합니까, 아니면 컴파일러에 따라 달라지나요?이 코드를 사용하도록 변경하는 것이 더 나을까요? malloc 그리고 free 대신에?

도움이 되었습니까?

해결책

기술적으로는 일치하지 않는 할당자에 문제가 발생할 수 있다고 생각합니다. 하지만 실제로는 이 예제에서 올바른 작업을 수행하지 않는 컴파일러를 알지 못합니다.

더 중요한 것은 만약에 STRUCT 소멸자가 있는 경우(또는 제공되는 경우) 해당 생성자를 호출하지 않고 소멸자를 호출합니다.

물론, pStruct가 어디서 왔는지 안다면 할당과 일치하도록 삭제 시 이를 캐스팅하면 안 됩니다.

delete [] (BYTE*) pStruct;

다른 팁

개인적으로 사용하시면 더 좋을 것 같아요 std::vector 메모리를 관리하기 위해 delete.

std::vector<BYTE> backing(sizeof(STRUCT) + nPaddingSize);
STRUCT* pStruct = (STRUCT*)(&backing[0]);

지원이 범위를 벗어나면 pStruct 더 이상 유효하지 않습니다.

또는 다음을 사용할 수 있습니다.

boost::scoped_array<BYTE> backing(new BYTE[sizeof(STRUCT) + nPaddingSize]);
STRUCT* pStruct = (STRUCT*)backing.get();

또는 boost::shared_array 소유권을 옮겨야 하는 경우.

예, 메모리 누수가 발생합니다.

C++ Gotchas를 제외하고 다음을 참조하세요. http://www.informit.com/articles/article.aspx?p=30642 왜냐면.

Raymond Chen은 벡터가 어떻게 사용되는지 설명합니다. new 그리고 delete Microsoft 컴파일러의 스칼라 버전과 다릅니다...여기:http://blogs.msdn.com/oldnewthing/archive/2004/02/03/66660.aspx

IMHO 삭제를 다음과 같이 수정해야 합니다.

delete [] pStruct;

전환하는 것보다 malloc/free, 실수 없이 변경하는 것이 더 간단하기 때문입니다.)

그리고 물론 위에 표시된 변경을 더 간단하게 하는 것은 원래 할당의 캐스팅으로 인해 잘못된 것입니다.

delete [] reinterpret_cast<BYTE *>(pStruct);

그래서 아마 전환하기가 쉬울 것 같아요 malloc/free 결국 ;)

코드의 동작은 정의되지 않습니다.운이 좋을 수도 있고 아닐 수도 있고 컴파일러에서 작동할 수도 있지만 실제로는 올바른 코드가 아닙니다.여기에는 두 가지 문제가 있습니다.

  1. 그만큼 delete 배열이어야 합니다 delete [].
  2. 그만큼 delete 할당된 유형과 동일한 유형에 대한 포인터에서 호출되어야 합니다.

따라서 완전히 정확하려면 다음과 같은 작업을 수행하고 싶습니다.

delete [] (BYTE*)(pStruct);

C++ 표준에는 다음과 같이 명확하게 명시되어 있습니다.

delete-expression:
             ::opt delete cast-expression
             ::opt delete [ ] cast-expression

첫 번째 대안은 배열이 아닌 객체에 대한 것이고 두 번째 대안은 배열에 대한 것입니다.피연산자는 포인터 유형이거나 포인터 유형으로의 단일 변환 함수(12.3.2)를 갖는 클래스 유형을 가져야 합니다.결과에는 void 유형이 있습니다.

첫 번째 대안(객체 삭제)에서 삭제 피연산자의 값은 배열이 아닌 객체에 대한 포인터여야 합니다. [...] 그렇지 않은 경우 동작은 정의되지 않습니다.

피연산자의 값 delete pStruct 배열에 대한 포인터입니다. char, 정적 유형(STRUCT*).따라서 코드의 형식이 잘못되어 있고 이 경우 합리적인 실행 파일을 생성하는 데 C++ 컴파일러가 필요하지 않기 때문에 메모리 누수에 대한 논의는 의미가 없습니다.

메모리가 누출될 수도 있고 누출될 수도 없으며 시스템이 충돌할 수도 있습니다.실제로 귀하의 코드를 테스트한 C++ 구현에서는 삭제 표현식 시점에서 프로그램 실행이 중단되었습니다.

다른 게시물에서 강조한 바와 같이:

1) 메모리 신규/삭제 호출 및 생성자/소멸자 호출 가능(C++ '03 5.3.4/5.3.5)

2) 어레이/비 어레이 버전 혼합 new 그리고 delete 정의되지 않은 동작입니다.(C++ '03 5.3.5/4)

소스를 보면 누군가가 검색하여 교체한 것으로 보입니다. malloc 그리고 free 위의 결과는 다음과 같습니다.C++에는 이러한 함수를 직접 대체하는 기능이 있습니다. 즉, 할당 함수를 호출하는 것입니다. new 그리고 delete 곧장:

STRUCT* pStruct = (STRUCT*)::operator new (sizeof(STRUCT) + nPaddingSize);
// ...
pStruct->~STRUCT ();  // Call STRUCT destructor
::operator delete (pStruct);

STRUCT의 생성자를 호출해야 하는 경우 메모리 할당을 고려한 다음 배치를 사용할 수 있습니다. new:

BYTE * pByteData = new BYTE[sizeof(STRUCT) + nPaddingSize];
STRUCT * pStruct = new (pByteData) STRUCT ();
// ...
pStruct->~STRUCT ();
delete[] pByteData;

@eric - 의견을 보내주셔서 감사합니다.그런데 당신은 계속해서 나를 미치게 만드는 말을 하고 있습니다.

이러한 런타임 라이브러리는 OS 독립적 인 일관된 구문에서 OS에 대한 메모리 관리 호출을 처리하며 런타임 라이브러리는 Linux, Windows, Solaris, AIX 등과 같은 OS간에 Malloc과 새로운 작업을 일관되게 만들 수 있습니다 ... .

이것은 사실이 아닙니다.예를 들어 컴파일러 작성자는 표준 라이브러리의 구현을 제공하며 이를 OS에서 완전히 자유롭게 구현할 수 있습니다. 매달린 방법.예를 들어, 그들은 자유롭게 malloc을 한 번 호출한 다음 블록 내에서 원하는 대로 메모리를 관리할 수 있습니다.

std 등의 API를 지원하므로 호환성을 제공합니다.동일합니다. 런타임 라이브러리가 모두 돌아서 정확히 동일한 OS 호출을 호출하기 때문이 아닙니다.

new 및 delete 키워드의 다양한 용도는 상당한 혼란을 야기하는 것 같습니다.C++에서 동적 개체를 생성하는 데는 항상 두 단계가 있습니다.원시 메모리 할당 및 할당된 메모리 영역에 새 개체 구성.객체 수명의 반대편에는 객체가 파괴되고 객체가 있던 메모리 위치가 할당 해제됩니다.

이러한 두 단계는 단일 C++ 문으로 수행되는 경우가 많습니다.

MyObject* ObjPtr = new MyObject;

//...

delete MyObject;

위의 대신 C++ 원시 메모리 할당 기능을 사용할 수 있습니다. operator new 그리고 operator delete 명시적 구성(배치를 통해) new) 및 파기하여 동등한 단계를 수행합니다.

void* MemoryPtr = ::operator new( sizeof(MyObject) );
MyObject* ObjPtr = new (MemoryPtr) MyObject;

// ...

ObjPtr->~MyObject();
::operator delete( MemoryPtr );

캐스팅이 포함되지 않고 할당된 메모리 영역에 한 가지 유형의 객체만 생성된다는 점에 주목하세요.다음과 같은 것을 사용하여 new char[N] 원시 메모리를 할당하는 방법은 논리적으로 기술적으로 올바르지 않습니다. char 새로 할당된 메모리에 객체가 생성됩니다.'그냥 작동'하지 않는 상황은 모르겠지만 원시 메모리 할당과 개체 생성 간의 구분이 모호해지기 때문에 권장하지 않습니다.

이 특별한 경우에는 두 단계를 분리해도 얻을 수 있는 이점이 없습니다. delete 하지만 초기 할당을 수동으로 제어해야 합니다.위 코드는 '모든 것이 작동하는' 시나리오에서 작동하지만 생성자가 다음과 같은 경우 원시 메모리가 누출됩니다. MyObject 예외가 발생합니다.할당 시점에 예외 처리기를 사용하여 이를 포착하고 해결할 수 있지만 배치 new 표현식으로 전체 구성을 처리할 수 있도록 사용자 정의 연산자 new를 제공하는 것이 더 깔끔할 것입니다.

class MyObject
{
    void* operator new( std::size_t rqsize, std::size_t padding )
    {
        return ::operator new( rqsize + padding );
    }

    // Usual (non-placement) delete
    // We need to define this as our placement operator delete
    // function happens to have one of the allowed signatures for
    // a non-placement operator delete
    void operator delete( void* p )
    {
        ::operator delete( p );
    }

    // Placement operator delete
    void operator delete( void* p, std::size_t )
    {
        ::operator delete( p );
    }
};

여기에는 몇 가지 미묘한 점이 있습니다.클래스 인스턴스에 충분한 메모리와 사용자가 지정할 수 있는 패딩을 할당할 수 있도록 클래스 배치 new를 정의합니다.이렇게 하기 때문에 메모리 할당은 성공했지만 구성은 실패할 경우 할당된 메모리가 자동으로 할당 해제되도록 일치하는 배치 삭제를 제공해야 합니다.불행하게도 게재위치 삭제에 대한 서명은 비배치 삭제에 대해 허용된 두 서명 중 하나와 일치하므로 실제 게재위치 삭제가 게재위치 삭제로 처리되도록 다른 형태의 비배치 삭제를 제공해야 합니다.(새 배치와 배치 삭제 모두에 추가 더미 매개변수를 추가하여 이 문제를 해결할 수 있었지만 이렇게 하려면 모든 호출 사이트에서 추가 작업이 필요했습니다.)

// Called in one step like so:
MyObject* ObjectPtr = new (padding) MyObject;

이제 단일 새 표현식을 사용하면 새 표현식의 일부가 발생하더라도 메모리가 누출되지 않는다는 것이 보장됩니다.

객체 수명의 다른 끝에서 우리는 연산자 삭제를 정의했기 때문에(그렇지 않더라도 객체에 대한 메모리는 원래 어떤 경우든 전역 연산자 new에서 나왔습니다) 다음은 동적으로 생성된 객체를 파괴하는 올바른 방법입니다. .

delete ObjectPtr;

요약!

  1. 캐스트가 없습니다! operator new 그리고 operator delete 원시 메모리를 다루면서 새로운 배치는 원시 메모리에 객체를 생성할 수 있습니다.명시적인 캐스트 void* 객체 포인터에 대한 것은 일반적으로 '그냥 작동'하더라도 논리적으로 잘못된 신호입니다.

  2. new[]와 delete[]를 완전히 무시했습니다.이러한 가변 크기 개체는 어떤 경우에도 배열에서 작동하지 않습니다.

  3. 새로운 배치는 새 표현식이 누출되지 않도록 허용하며, 새 표현식은 여전히 ​​파괴가 필요한 객체와 할당 해제가 필요한 메모리에 대한 포인터로 평가됩니다.일부 유형의 스마트 포인터를 사용하면 다른 유형의 누출을 방지하는 데 도움이 될 수 있습니다.플러스 측면에서 우리는 평범하게 만들었습니다. delete 대부분의 표준 스마트 포인터가 작동하도록 올바른 방법을 사용하십시오.

만약 너라면 정말 이런 일을 해야 한다면 아마도 교환원에게 전화해야 할 것입니다 new 곧장:

STRUCT* pStruct = operator new(sizeof(STRUCT) + nPaddingSize);

나는 이것을 이런 식으로 호출하면 생성자/소멸자 호출을 피할 수 있다고 믿습니다.

지금은 투표를 할 수 없지만 슬라이스라임의 답변 바람직하다 롭 워커의 답변, 문제는 할당자 또는 STRUCT에 소멸자가 있는지 여부와 관련이 없기 때문입니다.

또한 예제 코드가 반드시 메모리 누수를 일으키는 것은 아닙니다. 이는 정의되지 않은 동작입니다.거의 모든 일이 일어날 수 있습니다(나쁜 일이 아닌 것부터 멀리 떨어진 곳에서 충돌이 발생하는 것까지).

예제 코드에서는 정의되지 않은 단순하고 단순한 동작이 발생합니다.Slicedlime의 답변은 직접적이고 요점입니다(벡터는 ​​STL이므로 '벡터'라는 단어를 '배열'로 변경해야 한다는 주의 사항 포함).

이런 종류의 내용은 C++ FAQ(섹션 16.12, 16.13 및 16.14)에서 꽤 잘 다루고 있습니다.

http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.12

당신이 말하는 것은 벡터 삭제가 아니라 배열 삭제([])입니다.벡터는 std::Vector이며 해당 요소를 삭제합니다.

BYTE *로 다시 캐스팅하고 삭제할 수 있습니다.

delete[] (BYTE*)pStruct;

네, 그럴 수도 있습니다. new[]로 할당하고 delelte로 할당 해제하기 때문에 여기서는 malloc/free가 더 안전하지만 C++에서는 (해체)생성자를 처리하지 않으므로 사용하면 안 됩니다.

또한 코드에서는 분해자를 호출하지만 생성자는 호출하지 않습니다.일부 구조체의 경우 이로 인해 메모리 누수가 발생할 수 있습니다(생성자가 추가 메모리를 할당한 경우(예: 문자열))

올바르게 수행하는 것이 더 좋습니다. 이렇게 하면 생성자와 해체자도 올바르게 호출됩니다.

STRUCT* pStruct = new STRUCT;
...
delete pStruct;

모든 리소스의 획득/해제를 가능한 한 균형있게 유지하는 것이 항상 가장 좋습니다.이 경우 누출 여부를 말하기는 어렵습니다.이는 컴파일러의 벡터 (해제)할당 구현에 따라 다릅니다.

BYTE * pBytes = new BYTE [sizeof(STRUCT) + nPaddingSize];

STRUCT* pStruct = reinterpret_cast< STRUCT* > ( pBytes ) ;

 // do stuff with pStruct

delete [] pBytes ;

렌:문제는 pStruct가 STRUCT*이지만 할당된 메모리가 실제로 알 수 없는 크기의 BYTE[]라는 것입니다.따라서 delete[] pStruct는 할당된 메모리를 모두 할당 해제하지 않습니다.

C와 C++ 방식을 혼합하여 작업하는 것입니다.STRUCT 크기보다 더 많은 것을 할당하는 이유는 무엇입니까?왜 "새로운 STRUCT"가 아닌가?이 작업을 수행해야 한다면 이 경우에는 malloc과 free를 사용하는 것이 더 명확할 수 있습니다. 그러면 여러분이나 다른 프로그래머가 할당된 개체의 유형과 크기에 대해 가정할 가능성이 조금 줄어들 수 있기 때문입니다.

@matt cruikshank 당신은 삭제 []에게 전화하지 않는 것을 제안한 적이없고 OS를 정리하도록 제안하기 때문에주의를 기울이고 다시 쓴 내용을 읽어야합니다.그리고 힙을 관리하는 C++ 런타임 라이브러리에 대해서는 틀렸습니다.그렇다면 C++는 오늘날처럼 이식성이 없으며 충돌하는 응용 프로그램은 OS에 의해 정리되지 않을 것입니다.(C/C++를 이식 불가능하게 만드는 OS 특정 런타임이 있음을 인정)kernel.org의 Linux 소스에서 stdlib.h를 찾아보시기 바랍니다.C++의 새로운 키워드는 실제로 malloc과 동일한 메모리 관리 루틴과 통신합니다.

C++ 런타임 라이브러리는 OS 시스템 호출을 수행하며 힙을 관리하는 것은 OS입니다.런타임 라이브러리가 메모리를 해제할 시기를 나타내지만 실제로는 힙 테이블을 직접 탐색하지 않는다는 점에서 부분적으로 정확합니다.즉, 연결하는 런타임은 할당 또는 할당 취소를 위해 힙을 탐색하는 코드를 애플리케이션에 추가하지 않습니다.이는 Windows, Linux, Solaris, AIX 등의 경우입니다.이는 또한 Linux 커널 소스에서 malloc을 처리하지 않거나 Linux 소스에서 stdlib.h를 찾을 수 없는 이유이기도 합니다.이러한 최신 운영 체제에는 상황을 좀 더 복잡하게 만드는 가상 메모리 관리자가 있다는 것을 이해하십시오.

1G 상자에서 2G RAM에 대해 malloc을 호출하고 여전히 유효한 메모리 포인터를 얻을 수 있는 이유가 궁금하신가요?

x86 프로세서의 메모리 관리는 세 개의 테이블을 사용하여 커널 공간 내에서 관리됩니다.PAM(페이지 할당 테이블), PD(페이지 디렉터리) 및 PT(페이지 테이블).이것은 제가 말하는 하드웨어 수준입니다.C++ 응용 프로그램이 아닌 OS 메모리 관리자가 수행하는 작업 중 하나는 BIOS 호출을 통해 부팅 중에 상자에 설치된 실제 메모리의 양을 확인하는 것입니다.OS는 또한 애플리케이션에 권한이 없는 메모리에 액세스하려고 할 때와 같은 예외를 처리합니다.(GPF 일반 보호 오류).

Matt와 같은 말을 하고 있을 수도 있지만 후드 아래 기능을 약간 혼동하고 계신 것 같습니다.저는 C/C++ 컴파일러를 유지 관리하는 데 사용하고 있습니다.

@ericmayo - cripes.글쎄요, VS2005를 실험해 보면 벡터 새로 만든 메모리의 스칼라 삭제에서 정직한 누출을 얻을 수 없습니다.내 생각에 컴파일러 동작은 여기서 "정의되지 않은" 것으로 생각됩니다. 이는 제가 소집할 수 있는 최선의 방어에 관한 것입니다.

하지만 당신은 인정해야 합니다. 원래 포스터가 말한 대로 하는 것은 정말 형편없는 관행입니다.

이 경우 C ++는 오늘날처럼 휴대용이 아니며 충돌 애플리케이션은 OS에 의해 정리되지 않을 것입니다.

하지만 이 논리는 실제로 적용되지 않습니다.내 주장은 컴파일러의 런타임이 OS가 반환하는 메모리 블록 내의 메모리를 관리할 수 있다는 것입니다.이것이 대부분의 가상 머신이 작동하는 방식이므로 이 경우 이식성에 반대하는 주장은 별로 의미가 없습니다.

@맷 크룩생크

"글쎄요, VS2005를 실험해 보면 Vector New로 만들어진 메모리의 스칼라 삭제에서 정직한 누출을 얻을 수 없습니다.내 생각에 컴파일러 동작은 여기서 "정의되지 않음"이며, 이것이 제가 소집할 수 있는 최선의 방어에 관한 것입니다."

나는 그것이 컴파일러 동작이거나 심지어 컴파일러 문제라는 데 동의하지 않습니다.지적한 대로 'new' 키워드는 컴파일되어 런타임 라이브러리에 연결됩니다.이러한 런타임 라이브러리는 OS 독립적인 일관된 구문으로 OS에 대한 메모리 관리 호출을 처리하고 해당 런타임 라이브러리는 Linux, Windows, Solaris, AIX 등과 같은 OS 간에 일관되게 malloc 및 새로운 작업을 만드는 일을 담당합니다. .이것이 제가 이식성 주장을 언급한 이유입니다.런타임이 실제로 메모리를 관리하지 않는다는 것을 증명하려는 시도입니다.

OS는 메모리를 관리합니다.

OS에 대한 런타임 libs 인터페이스..Windows에서는 가상 메모리 관리자 DLL입니다.이것이 stdlib.h가 Linux 커널 소스가 아닌 GLIB-C 라이브러리 내에서 구현되는 이유입니다.GLIB-C가 다른 OS에서 사용되는 경우 올바른 OS 호출을 만들기 위해 malloc 변경을 구현합니다.VS, 볼랜드 등에서..실제로 메모리를 관리하는 컴파일러와 함께 제공되는 라이브러리도 찾을 수 없습니다.그러나 malloc에 ​​대한 OS별 정의를 찾을 수 있습니다.

Linux에 대한 소스가 있으므로 거기에서 malloc이 어떻게 구현되는지 살펴볼 수 있습니다.malloc이 실제로 GCC 컴파일러에서 구현되어 기본적으로 메모리를 할당하기 위해 커널에 두 개의 Linux 시스템 호출을 수행하는 것을 볼 수 있습니다.결코, malloc 자체가 실제로 메모리를 관리하지 않습니다!

그리고 나에게서 그것을 빼앗지 마십시오.Linux OS의 소스 코드를 읽거나 K&R이 이에 대해 말하는 내용을 볼 수 있습니다.다음은 C의 K&R에 대한 PDF 링크입니다.

http://www.oberon2005.ru/paper/kr_c.pdf

149페이지 끝 부분을 참조하세요."malloc 및 free에 대한 호출은 어떤 순서로든 발생할 수 있습니다.Malloc은 필요에 따라 더 많은 메모리를 얻기 위해 운영 체제를 요구합니다.이러한 루틴은 상대적으로 기계 독립적인 방식으로 기계 종속 코드를 작성하는 데 관련된 몇 가지 고려 사항을 설명하고 구조, 공용체 및 typedef의 실제 적용도 보여줍니다.

"그래도 인정해야 합니다. 원래 포스터에서 말한 대로 행하는 것은 정말 형편없는 관행입니다."

아, 저는 거기에 동의하지 않습니다.내 요점은 원본 포스터의 코드가 메모리 누수를 유발하지 않는다는 것입니다.그게 내가 말한 전부입니다.나는 모범 사례 측면에 대해 언급하지 않았습니다.코드가 삭제를 호출하므로 메모리가 확보됩니다.

귀하를 변호하기 위해 원본 포스터의 코드가 종료되지 않거나 삭제 호출에 도달하지 않은 경우 코드에 메모리 누수가 있을 수 있지만 나중에 삭제가 호출되는 것을 보았다고 말했기 때문에 동의합니다."그러나 나중에 삭제 호출을 사용하여 메모리가 해제됩니다."

게다가 내가 그렇게 응답한 이유는 OP의 설명 "구조 크기가 가변 길이 문자열에 따라 달라지는 가변 길이 구조(TAPI)" 때문이었습니다.

그 말은 그가 수행 중인 캐스트에 대한 할당의 동적 특성에 대해 의문을 제기하고 결과적으로 메모리 누수가 발생하는지 궁금해하는 것처럼 들렸습니다.당신이 원한다면 나는 줄 사이를 읽고있었습니다;).

위의 훌륭한 답변 외에도 다음을 추가하고 싶습니다.

귀하의 코드가 Linux에서 실행되거나 Linux에서 컴파일할 수 있다면 다음을 통해 실행하는 것이 좋습니다. 발그린드.이는 훌륭한 도구입니다. 이 도구가 생성하는 수많은 유용한 경고 중에서 메모리를 배열로 할당한 다음 비배열로 해제할 때(또는 그 반대로) 알려줄 수도 있습니다.

new 연산자를 사용하고 삭제합니다.

struct STRUCT
{
  void *operator new (size_t)
  {
    return new char [sizeof(STRUCT) + nPaddingSize];
  }

  void operator delete (void *memory)
  {
    delete [] reinterpret_cast <char *> (memory);
  }
};

void main()
{
  STRUCT *s = new STRUCT;
  delete s;
}

나는 메모리 누수가 없다고 생각합니다.

STRUCT* pStruct = (STRUCT*)new BYTE [sizeof(STRUCT) + nPaddingSize];

이는 운영 체제 내에서 해당 메모리에 대한 포인터가 반환되는 메모리 할당 호출로 변환됩니다.메모리가 할당될 때의 크기는 다음과 같습니다. sizeof(STRUCT) 그리고 크기 nPaddingSize 기본 운영 체제에 대한 메모리 할당 요청을 이행하기 위해 알려질 것입니다.

따라서 할당된 메모리는 운영 체제의 전역 메모리 할당 테이블에 "기록"됩니다.메모리 테이블은 포인터로 인덱싱됩니다.따라서 삭제에 대한 해당 호출에서 원래 할당된 모든 메모리는 사용 가능해집니다.(메모리 조각화는 이 영역에서도 인기 있는 주제입니다).

보시다시피 C/C++ 컴파일러는 메모리를 관리하지 않고 기본 운영 체제가 관리합니다.

나는 더 깨끗한 방법이 있다는 데 동의하지만 OP는 이것이 레거시 코드라고 말했습니다.

간단히 말해서, 허용된 답변에서는 메모리 누수가 있다고 믿기 때문에 메모리 누수가 발생하지 않습니다.

롭 워커 회신하다 좋다.

약간만 추가하면 생성자 또는/및 소멸자가 없어서 기본적으로 원시 메모리 덩어리를 할당하고 해제해야 하는 경우 free/malloc 쌍을 사용하는 것이 좋습니다.

ericmayo.myopenid.com은 너무 틀려서 평판이 좋은 사람이 그를 비추천해야 합니다.

C 또는 C++ 런타임 라이브러리는 Eric이 지적한 것처럼 운영 체제에 의해 블록으로 제공되는 힙을 관리합니다.하지만 그것은 ~이다 메모리를 확보하고 거기에 있는 객체를 파괴하기 위해 어떤 런타임 호출을 수행해야 하는지 컴파일러에 지시하는 것은 개발자의 책임입니다.이 경우 C++ 런타임이 힙을 유효한 상태로 유지하려면 벡터 삭제(일명 delete[])가 필요합니다.PROCESS가 종료되면 OS가 기본 메모리 블록을 할당 해제할 만큼 똑똑하다는 사실은 개발자가 의존해야 할 사항이 아닙니다.이는 전혀 삭제를 호출하지 않는 것과 같습니다.

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