programing

일반적인 실장에서는 동적 메모리 할당이 C와 C++로 다른가요?

goodcopy 2022. 7. 2. 22:31
반응형

일반적인 실장에서는 동적 메모리 할당이 C와 C++로 다른가요?

한, 는 동적 메모리 하는 것은, 「 메모리 할당」이 「 메모리 할당은, 「동적 메모리 할당」을 하는 경우 뿐입니다.malloc()에서 가장 인 형식의 은 C++로 .::operator new()C스타일의 malloc도 C++로 제공되고 있어, 「아기 최초 할당」의 예도 코어 할당 기능으로 많이 사용되고 있습니다만, 현대의 컴파일러가 실제의 오퍼레이터를 어떻게 실장하고 있는지 궁금합니다.

그냥 얇은 포장지인가?malloc()아니면 일반적인 C++ 프로그램과 일반적인 C 프로그램의 메모리 할당 동작이 다르기 때문에 근본적으로 다르게 구현되는 것입니까?

[편집: 주요 차이점은 보통 다음과 같습니다. C 프로그램은 더 적은 수의 할당, 더 큰 할당, 더 긴 할당, C++ 프로그램은 더 적은 할당, 더 적은 할당, 짧은 할당입니다.틀렸다면 언제든지 참여해주세요.하지만 이 점을 고려한다면 도움이 될 것 같습니다.]

GCC와 같은 컴파일러는 하나의 코어 할당 실장만으로 모든 관련 언어에 사용할 수 있기 때문에 언어별로 할당 퍼포먼스를 최적화하기 위한 디테일에 차이가 있는지 궁금합니다.


업데이트: 좋은 답변 감사합니다!이 문제는 GCC에서 ptmalloc에 의해 완전히 해결된 것으로 보이며 MSVC에서도malloc심에있있 있있있다다MSVC-malloc의 경우, MSVC-malloc는?

다음은 에 의해 사용되는 구현입니다.g++ 4.6.1:

_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) throw (std::bad_alloc)
{
  void *p;

  /* malloc (0) is unpredictable; avoid it.  */
  if (sz == 0)
    sz = 1;
  p = (void *) malloc (sz);
  while (p == 0)
    {
      new_handler handler = __new_handler;
      if (! handler)
#ifdef __EXCEPTIONS
        throw bad_alloc();
#else
        std::abort();
#endif
      handler ();
      p = (void *) malloc (sz);
    }

  return p;
}

이것은, 에서 확인할 수 있습니다.libstdc++-v3/libsupc++/new_op.cc distrog++ 의 .

처럼 꽤 malloc.

많은 시스템에서 편집이 가능합니다.malloc은, 콜에 「」, 「」)mallopt또는 환경변수를 설정합니다.다음은 Linux에서 사용할 수 있는 몇 가지 기능에 대한 기사입니다.

위키피디아에 따르면glibc버전 2.3+ 는, 라고 하는 이름의 할당자의 수정 버전을 사용합니다.그 자체는 의 파생 버전입니다.dlmalloc더그 리에 의해 디자인되었습니다.흥미롭게도, Doug Lea에 대한 기사에서 다음과 같은 관점을 제시합니다(내 관점).

동적 메모리 할당에만 의존하는 C++ 프로그램을 작성한 후 할당기의 첫 버전을 작성했습니다.예상보다 훨씬 느리게 실행되거나 총 메모리 소비량이 훨씬 더 많다는 것을 알게 되었습니다.이는 실행 중인 시스템의 메모리 할당기 특성(주로 SunOs 및 BSD의 당시 최신 버전)에 기인합니다.이에 대응하기 위해 처음에는 C++에 특수 목적의 할당자를 다수 적었는데, 보통 다양한 클래스에 대해 연산자 new를 오버로드하여 작성했습니다.이 중 일부는 1989년 C++ 보고서 기사 컨테이너 클래스에 대한 일부 스토리지 할당 기법으로 수정된 C++ 할당 기법에 대한 백서에 설명되어 있습니다.

그러나, 나는 곧 동적으로 할당되어 많이 사용되는 경향이 있는 각각의 새로운 클래스에 대해 특별한 할당기를 구축하는 것은 내가 그 당시에 쓰고 있던 범용 프로그래밍 지원 클래스를 작성할 때. ( 1986년부터 1991년까지 나는 GNU C++ 라이브러리인 libg+의 주 집필자였습니다.)더 넓은 해결책이 필요했습니다--프로그래머가 매우 특별한 조건이 아닌 한 특별한 목적의 할당자를 쓰려는 유혹을 받지 않도록 일반적인 C++ C 부하에서 충분히 좋은 할당자를 쓰는 것입니다.

이 문서에서는 이 할당자의 주요 설계 목표, 알고리즘 및 구현 고려사항에 대해 설명합니다.

대부분의 구현에서operator new()그냥 전화하다malloc()사실 본 기준서조차 이를 디폴트 스트레이트로 제시하고 있다.물론, 고객 고유의 기능을 구현할 수 있습니다.operator new퍼포먼스를 향상시키려면 보통 클래스용이지만 디폴트로는 보통 콜만 합니다.malloc().

glibc new 연산자는 malloc 주위의 얇은 래퍼입니다.또한 glibc malloc은 다양한 크기 할당 요구에 대해 다른 전략을 사용합니다.구현 또는 적어도 코멘트는 여기에서 확인할 수 있습니다.

다음은 malloc.c의 댓글에서 발췌한 것입니다.

/*
47   This is not the fastest, most space-conserving, most portable, or
48   most tunable malloc ever written. However it is among the fastest
49   while also being among the most space-conserving, portable and tunable.
50   Consistent balance across these factors results in a good general-purpose
51   allocator for malloc-intensive programs.
52 
53   The main properties of the algorithms are:
54   * For large (>= 512 bytes) requests, it is a pure best-fit allocator,
55     with ties normally decided via FIFO (i.e. least recently used).
56   * For small (<= 64 bytes by default) requests, it is a caching
57     allocator, that maintains pools of quickly recycled chunks.
58   * In between, and for combinations of large and small requests, it does
59     the best it can trying to meet both goals at once.
60   * For very large requests (>= 128KB by default), it relies on system
61     memory mapping facilities, if supported.
*/

Visual C++의 경우,new표현은 나를 이 단편으로 이끈다.new.cpp:

#include <cstdlib>
#include <new>

_C_LIB_DECL
int __cdecl _callnewh(size_t size) _THROW1(_STD bad_alloc);
_END_C_LIB_DECL

void *__CRTDECL 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);
        }

VC++의 경우new또,malloc()불러.

퍼포먼스의 문제가 아닙니다.pA = new A와는 다른 부작용이 있다pA = (A*)malloc(sizeof(A));

두 번째 예에서는 A의 컨스트럭터가 호출되지 않습니다.같은 효과를 얻으려면 당신이 해야 한다

pA = (A*)malloc(sizeof(A));
new(pA)A();

여기서 new는 "new"입니다.

void* operator new(size_t sz, void* place) 
{ return place; }

언급URL : https://stackoverflow.com/questions/7443782/does-dynamic-memory-allocation-differ-in-c-and-c-in-popular-implementations

반응형