2012-04-29 3 views
6

나는 그것이 전 세계 여러 번 논의 된 매우 오래된 논쟁임을 알고있다. 그러나 현재 특정 경우에 정적 및 동적 배열간에 다른 방법을 사용해야하는 방식을 결정하는 데 문제가 있습니다. 사실, 나는 C++ 11을 사용하지 않았다. 정적 배열을 사용했을 것이다. 그러나 나는 둘 다로 동등한 이점이있을 수 있기 때문에 지금 혼란 스럽다.정적 배열 VS. C++ 11의 동적 배열

최초의 솔루션 :

template<size_t N> 
class Foo 
{ 
    private: 
     int array[N]; 

    public: 
     // Some functions 
} 

두 번째 솔루션 : 나는이 자신의 장점이 있기 때문에 선택하는 일이 없습니다

template<size_t N> 
class Foo 
{ 
    private: 
     int* array; 

    public: 
     // Some functions 
} 

:

  • 정적 배열이 빠릅니다을, 우리는 메모리 관리에 전혀 신경 쓰지 않습니다.
  • 동적 배열은 메모리가 할당되지 않은 한 아무 것도 계산하지 않습니다. 그런 다음에는 정적 배열보다 사용하기가 쉽지 않습니다. 하지만 C++ 11 이후에는 정적 배열에 사용할 수없는 이동 의미론에서 큰 이점을 얻을 수 있습니다.

나는 하나의 좋은 해결책이 있다고 생각하지 않지만 몇 가지 조언을 듣고 싶습니다. 아니면 모든 것을 생각하고 있는지 알고 싶습니다.

+2

두 가지 솔루션은 다음 중 하나 여야합니다. 첫 번째 솔루션 또는 첫 번째 솔루션 또는 벡터 및 size_t 템플릿이 없어야합니다.STL 컨테이너를 아무런 문제없이 사용할 수있는 곳에서는 원시 포인터를 사용하지 않아야합니다. – mfontanini

+13

@fontanini : C++ 11을 수정하려면 두 개의 솔루션이'std :: array '또는'std :: vector '이어야합니다. –

+1

@ DavidRodríguez-dribeas 예! – mfontanini

답변

5

나는 실제로 "그것에 달려있다". 옵션 2를 사용하지 마십시오. 변환 시간 상수를 사용하려면 항상 옵션 1 또는 std :: array를 사용하십시오. 여러분이 나열한 장점 중 하나는 동적 배열이 할당 될 때까지 아무 것도 쓸 수 없다는 것입니다. 실제로는 끔찍하고 큰 단점이 있으며 중요한 점을 지적해야합니다.

구성 단계가 두 개 이상인 개체는 절대로 사용하지 마십시오.. 절대로. 그것은 커다란 문신을 통해 기억에 헌신해야한다는 규칙입니다. 그냥 절대하지 마.

아직 살아 있지 않은 좀비 오브젝트가있을 때, 꽤 죽지는 않지만 생애 관리의 복잡성이 기하 급수적으로 커집니다. 당신은 모든 방법이 완전히 살아 있는지, 아니면 살아있는 것만을 체크해야합니다. 예외 안전은 소멸자의 특별한 경우가 필요합니다. 간단한 구조와 자동 파괴 대신에 N 개의 다른 장소에서 검사해야하는 요구 사항을 추가했습니다 (# methods + dtor). 그리고 컴파일러는 당신이 검사하는지 상관하지 않습니다. 그리고 다른 엔지니어는이 요구 사항을 방송하지 않으므로 검사하지 않고 변수를 사용하여 안전하지 않은 방식으로 코드를 조정할 수 있습니다. 그리고이 모든 메소드는 객체의 상태에 따라 여러 가지 동작을하므로 객체의 모든 사용자는 무엇을 기대해야 하는지를 알아야합니다. 좀비가 귀하의 (코드) 의 생명을 망칠 것입니다.

대신 프로그램에서 두 가지 다른 수명이있는 경우 두 개의 다른 개체를 사용하십시오. 하지만 이는 프로그램에 두 개의 다른 상태가 있음을 의미하므로 한 상태에는 하나의 객체 만 있고 두 상태에는 비동기 이벤트가 구분 된 상태 시스템이 있어야합니다. 두 지점 사이에 비동기 이벤트가 없으면 모두 하나의 기능 범위에 들어 맞으면 분리가 인공적이며 단일 단계 구성을 수행해야합니다.

번역 시간 크기가 동적 할당으로 변환되어야하는 유일한 경우는 크기가 스택에 비해 너무 큰 경우입니다. 그런 다음 메모리 최적화가 이루어지며 메모리와 프로파일 링 도구를 사용하여 최상의 결과를 확인해야합니다. 옵션 2는 절대로 좋지 않을 것입니다 (벌거 벗은 포인터를 사용합니다. 다시 RAII와 자동 정리 및 관리를 잃고, 불변성을 추가하고 코드를 더 복잡하고 쉽게 다른 사람이 깨뜨릴 수 있습니다). 비트 맵 (bitmask)에 의해 제안 된대로 벡터가 적절한 첫 번째 생각이 될 것입니다. 그러나 힙 할당 비용이 시간에 맘에 들지 않을 수도 있습니다. 다른 옵션은 응용 프로그램 이미지의 정적 공간 일 수 있습니다. 그러나 다시 한번 말하지만, 이러한 것들은 메모리 제약 조건이 있다고 판단한 후에는 실제 측정 가능한 요구에 의해 결정되어야합니다.

+0

그래, 네 임무가 맞는거야. 내 코드를 다시 읽을 때, 메모리가 구성되어 있기 때문에 실제로는 좀비 오브젝트가 없다는 것을 깨달았습니다. 걱정하지 마십시오. 맞습니다. 단 하나의 이점은 마지막에 이동 작업에서 얻은 이득입니다 (이미 사용 된 경우 std :: vector에 의해 제공됨). 벡터를 사용할 때의 단점은 std :: array에 비해 약간의 오버 헤드가있을뿐입니다. 하지만 std :: array에 이동 의미가 있는지 모르겠다. ... – Morwenn

+0

스택에서 일반적으로 이동이 필요하지 않지만 반환 값 최적화가 필요하다. 컴파일러에 따라 다르지만 매우 보편적이다. 이동이 사용될 수있는 다른 경우는 거의 항상 in-place (복사 없음)로 수행 할 수 있으며 복사가 필요할 때 실제로 필요합니다 (한 유형의 메모리를 다른 장소에 배치하는 경우). 따라서 이동이 작동하지 않습니다. – ex0du5

4

둘 다 사용하지 마십시오. 거의 모든 경우에 std::vector을 사용하는 것이 좋습니다. 다른 경우에는 크게 std::vector이 부족하여 일반적으로 대답 할 수없는 이유에 크게 의존합니다!

+0

나는 이미이 경험 법을 안다. 나는 professionnal 일을 위해, 나는 그것을 사용할 것입니다. 그러나 나는 실험을하고 경험을 쌓는 것을 좋아한다. 게다가, 나는 현재의 경우 무작위 접근 외에 다른 것을 필요로하지 않았다. 그래서 내가이 일에 내 손을 찰 생각 했지. 그리고, std :: vector는 구현에 의존하기 때문에 배열의 크기가 실제로 변경되지 않기 때문에이 클래스의 많은 인스턴스를 사용하면 큰 오버 헤드가 발생할 수 있습니다. – Morwenn

4

현재 특정 사례에서 다른 것보다 더 많이 사용해야하는 것을 결정하는 데 문제가 있습니다.

주어진 상황에 맞는 최적의 솔루션을 결정하려면 사례별로 옵션을 고려해야합니다. 즉, 일반화가 불가능합니다. 한 컨테이너가 모든 시나리오에 이상적이라면 다른 컨테이너는 쓸모 없게됩니다.

앞서 언급 한 것처럼 직접 작성하기 전에 std 구현을 사용해보십시오.

자세한 내용 :

  • 당신이 소비하는 스택의 양에주의

    고정 길이.

  • 동적 크기 컨테이너로 취급하는 경우 더 많은 메모리를 소비 할 수 있습니다.
  • 빠른 사본.

가변 길이

  • 재 할당 및 크기 조정 비용이 많이 드는 될 수 있습니다.
  • 필요한 것보다 많은 메모리를 사용할 수 있습니다.
  • 빠른 이동.

더 나은 선택은 또한 창조의 복잡성을 이해, 복사, 요소 유형의 등 할당이 필요합니다.

std 구현을 사용하는 경우 구현이 다를 수 있습니다.

마지막으로, 구현 세부 사항을 추상화하고 크기 및 컨텍스트에 따라 적절한 데이터 멤버를 동적으로 선택하는 일반 컨테이너 뒤에 세부 사항을 추상화하는 이러한 유형의 컨테이너를 만들 수 있습니다. 또한 기능을 사용 중지하거나 일부 작업 (예 : 값 비싼 사본)을 더 분명하게 만들 때 유용합니다.

요약하면 유형 및 사용법에 대해 많이 알아야하며 특정 시나리오에 대한 최적의 컨테이너 유형을 결정하기 위해 프로그램의 여러 측면을 측정해야합니다.

+1

현재 N <4에 대한 템플릿 전문화가 필요했기 때문에 N이 클수록 동적 배열을 정적 배열로 사용할 수 있다고 생각했습니다. 메모리는 한 번 할당되고 어레이는 크기가 조정되지 않습니다. 큰 오버 헤드가 아닙니다. 나는 당신의 대답의 마지막 부분에서 당신의 생각을 좋아합니다. 감사! – Morwenn

+0

@Morwenn 당신은 환영합니다 :) – justin

+1

복사 시간은 어떻게 다릅니 까? – ex0du5