어떤 경우에 malloc 및 / 또는 new를 사용합니까?


479

C ++에는 데이터를 할당하고 해제하는 여러 가지 방법이 있으며 전화를 걸면 이해합니다. malloc 를 걸고 연산자를 free사용할 때 new페어링해야 delete하며 두 가지를 혼합하는 것은 실수라는 것을 이해합니다 (예 : free()생성 된 무언가에 대한 호출) 와 new) 연산자,하지만 난 사용해야하는 경우에 명확하지 않다 malloc/ free내가 사용해야 할 때 new/ delete내 실제 프로그램입니다.

C ++ 전문가 인 경우 이와 관련하여 따르는 경험 규칙이나 규칙을 알려주십시오.


33
두 스타일을 혼합 할 수 없다는 알림을 추가하고 싶습니다. 즉, new를 사용하여 객체를 만든 다음 free ()를 호출하거나 malloc ()이 할당 한 블록을 삭제하려고 시도 할 수 없습니다. 아마 분명히 말할 것이지만 그럼에도 불구하고 ...
nsayer

32
좋은 답변, 내가 추가해야 할 것은 (보지 못했던) new / delete가 생성자 / 소멸자를 호출하지만 malloc / free는 그렇지 않습니다. 언급 할 가치가있는 차이점.
Bill K

현대 C ++에서는 여전히 둘 중 하나를 사용해야 할 이유를 찾으려고 노력하고 있습니다.
Rahly

또는 둘 다 사용하지 말고 std : shared_ptr <T>와 함께 사용하십시오. 그런 다음 전혀 삭제할 필요가 없습니다.
Vincent

답변:


387

C를 사용하지 않으면을 사용해서는 안됩니다 malloc . 항상 사용하십시오 new.

많은 양의 데이터가 필요한 경우 다음과 같이하십시오.

char *pBuffer = new char[1024];

이것이 올바르지는 않지만주의하십시오.

//This is incorrect - may delete only one element, may corrupt the heap, or worse...
delete pBuffer;

대신 데이터 배열을 삭제할 때이 작업을 수행해야합니다.

//This deletes all items in the array
delete[] pBuffer;

new키워드는 그 일의 C ++ 방법이며, 그것은 당신의 유형이 그 것이다 보장합니다 생성자가 호출 . new키워드는 더 형태 보증 된 반면 malloc입력-로부터 안전하지 않습니다 전혀.

내가 유용하다고 생각할 수있는 유일한 방법 은 데이터 버퍼크기malloc변경 해야하는 경우 입니다. new키워드는 같은 유사한 방법이 없습니다 realloc. 이 realloc기능은 메모리 청크 크기를보다 효율적으로 확장 할 수 있습니다.

new/ freemalloc/을 혼합 할 수는 없습니다 delete.

참고 :이 질문에 대한 일부 답변이 잘못되었습니다.

int* p_scalar = new int(5);  // Does not create 5 elements, but initializes to 5
int* p_array  = new int[5];  // Creates 5 elements

2
delete [] foo를 호출해야 할 때 delete foo를 호출하는 것과 관련하여 일부 컴파일러는이를 자동으로 수정하고 누출되지 않으며 다른 컴파일러는 첫 번째 항목과 누출 만 삭제합니다. 나는 몇 가지 코드로 이것들 중 일부를 가지고 있었고 valgrind는 당신을 위해 그것들을 찾을 것입니다.
KPexEA

30
올바른 삭제를 사용하지 않으면 결과가 정의되지 않습니다 . 잘못되었습니다. 그것이 옳은 일이나 일의 일부가 될 수 있다는 사실은 때로는 실명입니다.
Michael Burr

8
@ KPexEA : 일부 컴파일러가 실수를 고칠 수는 있지만 여전히 실수를 저지르는 것은 잘못입니다. :) 항상 적절한 곳에 delete []를 사용하십시오.
korona

62
"C를 사용하지 않으면 malloc을 사용해서는 안됩니다. 항상 새로운 것을 사용하십시오." 왜? 이기는 무엇입니까? 객체의 경우 구성이 필요하지만 메모리 블록의 경우 코딩 실수를 쉽게하는 두 가지 방법 (새롭고 쉽게 잡히는 () vs [], 덜 맞지 않는 배열과 스케일러를 새로 작성 및 삭제)을 명확하게 문서화합니다. 원시 메모리 블록에 대해 새 / 삭제를 사용하는 동기는 무엇입니까?
벤 Supnik

3
@DeadMG : 비동기 API 함수에서 사용할 배열을 만드는 경우 new[]보다 안전하지 std::vector않을까요? 를 사용 new[]하는 경우 포인터가 유효하지 않은 유일한 방법은 명시 적을 통하는 것입니다 delete. 반면 std::vector에 벡터 크기가 조정되거나 범위를 벗어날 때 할당 된 메모리 는 무효화 될 수 있습니다. ( 비동기 메서드가 여전히 보류중인 경우 new[]전화를 걸지 못할 가능성을 허용 delete해야합니다. 비동기 작업을 포기해야 할 경우 콜백을 통해 삭제를 준비해야 할 수도 있습니다) .
supercat

144

짧은 대답은 mallocC ++에 사용하지 않는 것이 좋습니다. mallocC ++과 함께 사용 new하면 극복 할 수있는 많은 결함이 있습니다.

C ++ 코드의 새로운 기능으로 해결 된 결함

  1. malloc의미있는 방식으로 타입 안전하지 않습니다. C ++에서는에서 반환을 캐스트해야합니다 void*. 잠재적으로 많은 문제가 발생합니다.

    #include <stdlib.h>
    
    struct foo {
      double d[5];
    }; 
    
    int main() {
      foo *f1 = malloc(1); // error, no cast
      foo *f2 = static_cast<foo*>(malloc(sizeof(foo)));
      foo *f3 = static_cast<foo*>(malloc(1)); // No error, bad
    }
  2. 그래도 더 나쁘다. 문제의 유형이 POD (일반 데이터) 인 경우 첫 번째 예에서 malloc와 같이 반 감각으로 메모리를 할당 하는 데 사용할 수 있습니다 f2.

    유형이 POD인지는 분명하지 않습니다. 주어진 유형이 컴파일러 오류가 발생하지 않고 문제를 디버깅하기가 매우 어려워 POD에서 비 POD로 변경 될 수 있다는 사실이 중요한 요소입니다. 예를 들어, 유지 관리 중 누군가 나중에 foo더 이상 POD가 아닌 변경을 수행 한 경우 컴파일 타임에 원하는대로 명백한 오류가 나타나지 않습니다. 예를 들면 다음과 같습니다.

    struct foo {
      double d[5];
      virtual ~foo() { }
    };

    만들 것 mallocf2명백한 진단하지 않고, 또한이 될 나쁜. 여기의 예는 사소한 것이지만 실수로 비 POD를 훨씬 더 멀리 도입 할 수 있습니다 (예 : 기본 클래스에서 비 POD 멤버를 추가하여). C ++ 11 / boost is_pod가있는 경우이 가정이 올바른지 확인하고 올바르지 않은 경우 오류를 생성하는 데 사용할 수 있습니다 .

    #include <type_traits>
    #include <stdlib.h>
    
    foo *safe_foo_malloc() {
      static_assert(std::is_pod<foo>::value, "foo must be POD");
      return static_cast<foo*>(malloc(sizeof(foo)));
    }

    boost는 형식이 C ++ 11 또는 다른 컴파일러 확장이없는 POD인지 확인할 수 없지만 .

  3. mallocNULL할당이 실패하면를 반환 합니다. new던질 것 std::bad_alloc입니다. 나중에 NULL포인터를 사용하는 동작 은 정의되어 있지 않습니다. 예외가 발생하면 예외가 깨끗하고 오류의 원인에서 발생합니다. 포장 malloc모든 호출에서 적절한 검사와 함께하는 경향이 지루하고 오류가 보인다. (좋은 일을 모두 취소하기 위해서는 한 번만 잊어야합니다). 예외적으로 호출자가 의미있게 처리하기 NULL가 훨씬 어려운 수준에서 호출자가 처리 할 수있는 수준으로 전파 될 수 있습니다 . safe_foo_malloc예외를 발생 시키거나 프로그램을 종료하거나 핸들러를 호출하도록 함수를 확장 할 수 있습니다 .

    #include <type_traits>
    #include <stdlib.h>
    
    void my_malloc_failed_handler();
    
    foo *safe_foo_malloc() {
      static_assert(std::is_pod<foo>::value, "foo must be POD");
      foo *mem = static_cast<foo*>(malloc(sizeof(foo)));
      if (!mem) {
         my_malloc_failed_handler();
         // or throw ...
      }
      return mem;
    }
  4. 기본적 malloc으로 C 기능이며 newC ++ 기능입니다. 결과적 malloc으로 생성자와 잘 작동하지 않으므로 바이트 덩어리 할당 만 살펴 봅니다. safe_foo_malloc게재 위치를 사용하도록 추가 확장 할 수 있습니다 new.

    #include <stdlib.h>
    #include <new>
    
    void my_malloc_failed_handler();
    
    foo *safe_foo_malloc() {
      void *mem = malloc(sizeof(foo));
      if (!mem) {
         my_malloc_failed_handler();
         // or throw ...
      }
      return new (mem)foo();
    }
  5. 우리의 safe_foo_malloc기능은 매우 일반적이지 않습니다. 이상적으로는 모든 유형을 처리 할 수있는 것을 원할 것입니다 foo. 기본이 아닌 생성자를위한 템플릿 및 가변 템플릿을 사용하여이를 달성 할 수 있습니다.

    #include <functional>
    #include <new>
    #include <stdlib.h>
    
    void my_malloc_failed_handler();
    
    template <typename T>
    struct alloc {
      template <typename ...Args>
      static T *safe_malloc(Args&&... args) {
        void *mem = malloc(sizeof(T));
        if (!mem) {
           my_malloc_failed_handler();
           // or throw ...
        }
        return new (mem)T(std::forward(args)...);
      }
    };

    이제 우리가 지금까지 식별 한 모든 문제를 해결함에있어 기본 new연산자를 실제로 재창조했습니다 . 당신이 사용 malloc하고 배치 하려는 경우, 당신은 new뿐만 아니라 new시작 하는 데 사용할 수 있습니다 !


27
너무 나쁜 C있어 ++ 제작 structclass기본적으로 동일한 것을 의미; structPOD를 위해 예약되어 있고 모든 class유형이 비 POD로 추정되는 데 문제가 있었는지 궁금합니다 . C ++의 발명을 앞둔 코드로 정의 된 모든 유형은 반드시 POD 일 것이므로 이전 버전과의 호환성이 문제가되지 않을 것이라고 생각합니다. POD 이외의 유형을 선언하는 struct것보다 장점 이 class있습니까?
supercat

1
A는 늦었지만가 만드는 밝혀 비트 @supercat structclass거의 같은 일이 지금이라는 깔끔한 기능을 할 수있는 멋진 디자인 결정이었다 않는다 (허브)에서 "메타 클래스는" .
Rakete1111

@ Rakete1111 : 언뜻보기에이 제안은 달러 접두사 키워드를 사용하는 언어 버전을 사전 처리하는 것처럼 보입니다 $class. 확실 함께 할 수있다 그 어떤 아니에요 classstruct하지만,되는 동의어.
supercat

@supercat 타입 시스템이 더 분기 된 것입니다. 함으로써 classstruct효과적으로 같은 뜻, 당신은 그들 (에 임의의 변환을 할 수있는 $class메이킹의 걱정없이) classstruct그 반대의 경우도 마찬가지입니다.
Rakete1111

@ Rakete1111 : 특정 유형의 연산 및 변환이 일부 유형에서는 안전하지만 다른 유형에서는 안전하지 않은 경우 유형에서 직접 식별하고 컴파일러가 안전하지 않은 연산 및 변환을 거부하면 메타 클래스가 변경 된 것보다 낫습니다. PODS에만 적합한 방식을 사용하여 비 PODS로 자동 변경하십시오.
supercat

53

로부터 C ++ FQA 라이트 :

[16.4] 신뢰할 수있는 오래된 malloc () 대신 new를 사용해야하는 이유는 무엇입니까?

FAQ : 생성자 / 소멸자를 호출 / 삭제합니다. new는 타입이 안전하고 malloc은 그렇지 않습니다. new는 클래스에 의해 재정의 될 수 있습니다.

FQA : 생성자, 소멸자 및 연산자 오버로딩이 가비지 (가비지 수집이 없을 때 발생하는 일 참조) 및 유형 안전 문제가 실제로 매우 작기 때문에 FAQ에서 언급 한 새로운 미덕은 미덕이 아닙니다. malloc이 리턴 한 void *를 올바른 포인터 유형으로 캐스트하여 유형이 지정된 포인터 변수에 할당합니다.

오, 신뢰할 수있는 오래된 malloc을 사용하면 똑같이 신뢰할 수 있고 오래된 realloc을 사용할 수 있습니다. 유감스럽게도 우리에게는 새로운 운영자 갱신이나 무언가가 없습니다.

그럼에도 불구하고, 언어가 C ++ 인 경우에도 언어 전체에 사용되는 공통 스타일과의 편차를 정당화하기에 충분하지 않은 것은 새로운 것이 아닙니다. 특히 사소하지 않은 생성자를 가진 클래스는 단순히 객체를 malloc하면 치명적인 방식으로 잘못 작동합니다. 그렇다면 코드 전체에서 new를 사용하지 않는 이유는 무엇입니까? 사람들은 운영자에게 새로운 과부하를 거의주지 않기 때문에 너무 방해가되지 않을 것입니다. 새로운 과부하가 발생하면 언제든지 중지하도록 요청할 수 있습니다.

죄송합니다. 저항 할 수 없었습니다. :)


7
그것은 폭동입니다 ! 감사.
dmckee --- 전 운영자 고양이 14

8
저자의 C ++에 대한 편견을 분명히 보여주기 때문에이 의견을 진지하게 받아 들일 수 없습니다. C ++는 성능 지향 소프트웨어를 만드는 데 사용되는 언어이며 가비지 수집기는 그 목적에 해로울 수 있습니다. 나는 당신의 전체 답변에 동의하지 않습니다!
Miguel

1
@Miguel 당신은 농담을 놓쳤다.
Dan Bechard

50

항상 C ++에서 new를 사용하십시오. 형식화되지 않은 메모리 블록이 필요한 경우 연산자 new를 직접 사용할 수 있습니다.

void *p = operator new(size);
   ...
operator delete(p);

3
흥미롭게도, 나는 이와 같은 원시 데이터 버퍼가 필요할 때 항상 부호없는 문자 배열을 할당했습니다.
Greg Rogers

의미는 다음과 같아야합니다. p_var = new type (initializer); 크기가 아닙니다.
브라이언 R. 본디

11
operator new를 직접 호출하지 않으면 매개 변수로 할당하는 데 바이트 수가 필요합니다.
Ferruccio

1
잘 모르겠습니다.이 구문에 대해 들어 본 적이 없습니다.
브라이언 R. 본디

9
의 반대는 operator new입니다 operator delete. deletetype 식 을 호출하는 것은 잘 정의 된 작업이 아닙니다 void*.
CB Bailey

33

사용하다 malloc단지 C-중심의 라이브러리와 API에 의해 관리 될 것입니다 메모리를 할당합니다. 제어하는 모든 항목에 및 (및 변형)을 사용하십시오 .free newdelete[]


10
또한 잘 작성된 C 라이브러리는 malloc을 숨기고 내부적으로 무료입니다. 이것이 C 프로그래머가 작동하는 방식입니다.
Dacav

@dmckee 당신은 malloc과 무료로 c 중심 라이브러리를 사용하는 C ++의 예를 가지고 있습니까?
milesma

1
@Dacav : C 함수가 함수가 리턴 된 후에 계속 사용해야하는 오브젝트에 대한 포인터를 허용하고 호출자가 오브젝트가 언제 필요한지 알 수있는 방법이 없으면 함수에 대해 완벽하게 합리적입니다 로 포인터를 작성했음을 지정합니다 malloc. 마찬가지로 함수 strdup가 오브젝트를 작성하여 호출자에게 리턴해야하는 경우 호출자가 free오브젝트가 더 이상 필요하지 않을 때 오브젝트를 호출하도록 지정하는 것이 합리적 입니다. 그러한 함수들이 어떻게 malloc / free를 호출자에게 노출시키지 않을 수 있습니까?
supercat

@ supercat, C는 객체를 전혀 인식하지 못하기 때문에 C 함수가 객체에 대한 포인터를 허용하는 데 본질적으로 잘못된 것이 있습니다. 일반적으로 가장 좋은 방법은 C에서도 할당 / 할당 해제에 시맨틱 래퍼를 갖는 것입니다. C 라이브러리가 호출자에게 메모리를 사전 할당 및 / 또는 할당 해제하도록 요청하는 경우 여전히 수용 가능하지만 유연성이 떨어질 수 있습니다. C 함수가이를 수행하고 할당 된 메모리에 대한 소유권을 주장하는 경우, malloc을 사용하여이를 암시 적으로 할당해야합니다.
Dacav

@supercat 모든 사람이 사용한 확실한 매일 패키지의 한 예는 libgmp입니다. 그러한 암호화에 기반한 오픈 소스 암호화 또는 소프트웨어를 사용한 적이 있다면 (아마도 가능할 것입니다) 자체 내부 데이터를 늘리고 줄여야하는 임의의 정밀 산술 라이브러리를 사용했을 것입니다. 이것은 초기화 함수를 사용하여 수행됩니다 ... 그리고 C ++에서 다시 컴파일하지 않고 C ++에서 libgmp 인 C 코드를 어떻게 사용합니까? 이제 (링커)를 염두에두고 생각해보십시오. 현명한 사람 mallocC ++에 넣었을 까요?
자폐증

31

새로운 대 malloc ()

1) new이다 연산자 반면malloc() A는 기능 .

2) 생성자new 호출 하지만 malloc()그렇지 않습니다.

3) 정확한 데이터 유형을new 반환 하는 동안malloc() 반환 무효 * .

4) new절대 반환하지 않습니다 NULL 동안 (실패가 발생합니다) malloc()반환 NULL을

5) 메모리의 재 할당에 의해 처리되지 않는 new동안 malloc()


6
Hi, point 4)의 경우, 실패시 new가 NULL을 반환하도록 지시 할 수 있습니다. char* ptr = new (std::nothrow) char [323232];
Singh

1
6) new는 생성자 인수로 작성하지만 malloc은 크기를 사용합니다.
Evan Moran

new기능 도 있습니다
Ma Ming

C에서 재 할당 하기에 너무 기울어 졌다면 , realloc대신에 사용 하기를 바라며 malloc포인터 변수를로 초기화하는 것이 NULL좋습니다. 반면에 C ++에서 크기 조정 가능한 메모리 청크 를 원한다면 ... 또는 파일 std::vector과 반대로 제안 할 것 realloc입니다.
자폐증

19

귀하의 질문에 대답하기 위해, 당신은 알아야 사이의 차이를 mallocnew . 차이점은 간단합니다.

malloc 메모리new 할당하고 메모리할당하고 메모리할당 하는 객체 의 생성자호출합니다 .

따라서 C로 제한되지 않는 한, 특히 C ++ 객체를 다룰 때 malloc을 사용해서는 안됩니다. 그것은 프로그램을 깨기위한 레시피 일 것입니다.

또한 사이의 차이 free와는 delete상당히 동일합니다. 차이점은 delete메모리를 비우는 것 외에도 객체의 소멸자를 호출 한다는 것입니다.


13

malloc와 사이에는 큰 차이가 new있습니다.malloc메모리를 할당합니다. C에서는 메모리가 대량이기 때문에 C에 적합합니다.

C ++에서 POD 유형 (C 유형과 유사한)을 처리하지 않는 경우 실제로 메모리 위치에서 생성자를 호출하여 객체를 가져와야합니다. 많은 C ++ 기능이 개체를 자동으로 비 POD로 만들기 때문에 비 POD 유형은 C ++에서 매우 일반적입니다.

new메모리를 할당 하고 해당 메모리 위치에 객체를 만듭니다. 비 POD 유형의 경우 생성자를 호출하는 것을 의미합니다.

이런 식으로하면 :

non_pod_type* p = (non_pod_type*) malloc(sizeof *p);

획득 한 포인터는 객체를 가리 키지 않으므로 역 참조 할 수 없습니다. 사용하기 전에 생성자를 호출해야합니다 (이것은 배치를 사용하여 수행됩니다)new ).

반면에 다음과 같은 경우 :

non_pod_type* p = new non_pod_type();

항상 유효한 포인터를 얻습니다. new객체를 생성 습니다.

POD 유형의 경우에도 둘 사이에는 큰 차이가 있습니다.

pod_type* p = (pod_type*) malloc(sizeof *p);
std::cout << p->foo;

이 코드는 작성된 POD 오브젝트 malloc가 초기화되지 않았기 때문에 지정되지 않은 값을 인쇄합니다 .

을 사용하면 new호출 할 생성자를 지정하여 잘 정의 된 값을 얻을 수 있습니다.

pod_type* p = new pod_type();
std::cout << p->foo; // prints 0

실제로 원하는 경우 new초기화를 사용 하여 초기화되지 않은 POD 객체를 얻을 수 있습니다 . 이에 대한 자세한 내용 은 이 다른 답변 을 참조하십시오.

또 다른 차이점은 실패시 동작입니다. 메모리 할당에 실패하면 mallocnull 포인터를 반환 new하고 예외 를 throw합니다.

전자는 사용하기 전에 반환 된 모든 포인터를 테스트해야하지만 후자는 항상 유효한 포인터를 생성합니다.

이러한 이유로 C ++ 코드에서는을 사용 new하지 말고을 사용해야 malloc합니다. 그러나 new"개방형"을 사용해서는 안됩니다 . 나중에 공개해야하는 리소스를 확보하기 때문입니다. 사용할 때 new결과를 즉시 자원 관리 클래스로 전달해야합니다.

std::unique_ptr<T> p = std::unique_ptr<T>(new T()); // this won't leak

7

동적 할당은 객체의 수명이 생성 된 범위와 달라야하고 (범위를 더 작게 만들기 위해 유지됨) 값별로 저장하지 않는 특정 이유가있는 경우에만 필요합니다. 작업.

예를 들면 다음과 같습니다.

 std::vector<int> *createVector(); // Bad
 std::vector<int> createVector();  // Good

 auto v = new std::vector<int>(); // Bad
 auto result = calculate(/*optional output = */ v);
 auto v = std::vector<int>(); // Good
 auto result = calculate(/*optional output = */ &v);

C ++ 11부터 std::unique_ptr할당 된 메모리의 소유권을 포함하는 할당 된 메모리를 처리 해야 합니다.std::shared_ptr소유권을 공유해야 할 때 생성되었습니다. (좋은 프로그램에서 기대하는 것보다 덜 필요합니다)

인스턴스 만들기가 정말 쉬워집니다.

auto instance = std::make_unique<Class>(/*args*/); // C++14
auto instance = std::make_unique<Class>(new Class(/*args*/)); // C++11
auto instance = std::make_unique<Class[]>(42); // C++14
auto instance = std::make_unique<Class[]>(new Class[](42)); // C++11

C ++ 17은 또한 std::optional메모리 할당을 요구하지 않도록 추가합니다.

auto optInstance = std::optional<Class>{};
if (condition)
    optInstance = Class{};

'인스턴스'가 범위를 벗어나면 메모리가 정리됩니다. 소유권 이전도 쉽습니다.

 auto vector = std::vector<std::unique_ptr<Interface>>{};
 auto instance = std::make_unique<Class>();
 vector.push_back(std::move(instance)); // std::move -> transfer (most of the time)

그래서 언제 아직도 필요 new합니까? C ++ 11부터는 거의 없습니다. 대부분은 std::make_unique원시 포인터를 통해 소유권을 이전하는 API에 도달 할 때까지 사용 합니다.

 auto instance = std::make_unique<Class>();
 legacyFunction(instance.release()); // Ownership being transferred

 auto instance = std::unique_ptr<Class>{legacyFunction()}; // Ownership being captured in unique_ptr

C ++ 98 / 03에서는 수동 메모리 관리를 수행해야합니다. 이 경우 최신 버전의 표준으로 업그레이드하십시오. 붙어있는 경우 :

 auto instance = new Class(); // Allocate memory
 delete instance;             // Deallocate
 auto instances = new Class[42](); // Allocate memory
 delete[] instances;               // Deallocate

메모리 누수가 없도록 소유권을 올바르게 추적해야합니다! 이동 의미론도 아직 작동하지 않습니다.

그렇다면 C ++에서 malloc이 언제 필요할까요? 유효한 이유는 메모리를 할당하고 나중에 new 배치를 통해 메모리를 초기화하는 것입니다.

 auto instanceBlob = std::malloc(sizeof(Class)); // Allocate memory
 auto instance = new(instanceBlob)Class{}; // Initialize via constructor
 instance.~Class(); // Destroy via destructor
 std::free(instanceBlob); // Deallocate the memory

위의 내용이 유효하더라도 새로운 운영자를 통해서도 가능합니다. std::vector이에 대한 좋은 예입니다.

마지막으로, 우리는 여전히 방에 코끼리가 있습니다 C. 메모리가 C ++ 코드에서 할당되고 C 코드에서 해제되거나 다른 방법으로 해제되는 C 라이브러리로 작업해야하는 경우 malloc / free를 사용해야합니다.

이 경우 가상 함수, 멤버 함수, 클래스를 잊어 버리십시오 ... POD가있는 구조체 만 허용됩니다.

규칙에 대한 일부 예외 :

  • malloc이 적합한 고급 데이터 구조로 표준 라이브러리를 작성 중입니다.
  • 많은 양의 메모리를 할당해야합니다 (10GB 파일의 메모리 사본?)
  • 특정 구문을 사용하지 못하게하는 툴링이 있습니다.
  • 불완전한 유형을 저장해야합니다

6

몇 가지가 있습니다 new것을 수행 malloc하지 않습니다는 :

  1. new 해당 객체의 생성자를 호출하여 객체를 생성합니다.
  2. new 할당 된 메모리의 타입 캐스팅이 필요하지 않습니다.
  3. 할당 할 메모리 양이 필요하지 않고 여러 개체를 구성해야합니다.

따라서를 사용하는 경우 malloc위의 작업을 명시 적으로 수행해야합니다. 이는 항상 실용적이지는 않습니다. 또한 new오버로드 될 수는 있지만로드 malloc할 수 없습니다.


5

구성 / 파괴가 필요하지 않고 재 할당이 필요한 데이터 (예 : 큰 정수)가 필요한 경우 malloc / free가 realloc을 제공하므로 new-memcpy보다 훨씬 빠릅니다. -delete (내 Linux 상자에 있지만 플랫폼에 따라 다를 수 있습니다). POD가 아니고 구성 / 파괴가 필요한 C ++ 오브젝트로 작업하는 경우 new 및 delete 연산자를 사용해야합니다.

어쨌든, 속도 향상을 이용할 수 있다면 (때로는 큰 배열을 재 할당하는 경우 중요한 경우), 둘 다를 사용하지 않아야하는 이유를 알 수 없습니다. realloc이 줄 수 있습니다.

그래도 필요하지 않으면 C ++에서 새 / 삭제를 고수해야합니다.


3

C 코드를 C ++로 이식하려는 경우 malloc () 호출을 그대로 둘 수 있습니다. 새로운 C ++ 코드의 경우 new를 대신 사용하는 것이 좋습니다.


3

C ++를 사용하는 경우 malloc / calloc 대신 new / delete를 연산자로 사용하십시오. malloc / calloc의 경우 다른 헤더를 포함해야합니다. 동일한 코드에서 두 개의 다른 언어를 혼합하지 마십시오. 그들의 작업은 모든면에서 비슷하며 해시 테이블의 힙 세그먼트에서 동적으로 메모리를 할당합니다.


2

new 구조체의 기본값을 초기화하고 그 안의 참조를 자신에게 올바르게 연결합니다.

예 :

struct test_s {
    int some_strange_name = 1;
    int &easy = some_strange_name;
}

따라서 new struct test_smalloc'ed 버전에는 기본값이 없으며 인턴 참조는 초기화되지 않은 반면 작동하는 참조와 함께 초기화 된 구조를 반환합니다.


1

낮은 관점에서, new는 메모리를주기 전에 모든 메모리를 초기화하는 반면 malloc은 메모리의 원래 내용을 유지합니다.


4
new는 일반적으로 메모리를 초기화하지 않지만 그렇게 할 수있는 방법이 있습니다 : 그것에 대한 한 가지 토론 은 stackoverflow.com/questions/2204176/…
wjl

0

다음 시나리오에서는 생성자를 호출하므로 new를 사용할 수 없습니다.

class  B  {
private:
    B *ptr;
    int x;
public:
    B(int n)  {
        cout<<"B: ctr"<<endl;
        //ptr = new B;  //keep calling ctr, result is segmentation fault
        ptr = (B *)malloc(sizeof(B));
        x = n;
        ptr->x = n + 10;
    }
    ~B()  {
        //delete ptr;
        free(ptr);
        cout<<"B: dtr"<<endl;
    }
};

0

newdelete운영자는 반면, 클래스 및 구조에서 작동 할 수 mallocfree필요가 캐스팅 될하는 메모리 블록에서만 작동합니다.

를 사용 new/delete하면 할당 된 메모리를 필요한 데이터 구조로 캐스트 할 필요가 없으므로 코드를 개선하는 데 도움이됩니다.


0

new / delete 대신 malloc / free를 사용하는 것을 고려하는 드문 경우는 C ++에서 realloc과 비슷한 기능이 없기 때문에 realloc을 사용하여 할당 한 다음 (객체가 아닌 간단한 포드 유형) 할당 할 때입니다 (이를 사용하여 수행 할 수는 있지만) 더 많은 C ++ 접근 방식).


-4

malloc ()은 C에서 메모리를 동적으로 할당하는 데 사용되는 반면 동일한 작업은 c ++의 new ()에서 수행됩니다. 따라서 2 개 언어의 코딩 규칙을 혼합 할 수 없습니다. calloc과 malloc ()의 차이점을 요청하면 좋을 것입니다.


2
C ++에서 사용할 수 있지만 거의 항상 사용해서는 안됩니다 malloc.
interjay

1
또한 스마트 포인터를 통해 그렇게하지 않는 한 동적 메모리 할당을 피해야한다는 요점을 놓쳤습니다. 당신은 다른 현명한 고통을 위해 자신을 설정하고 있습니다
thecoshman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.