2015-01-09 6 views
0

은 내가 C++ 작성한 이후 오랜만, 그래서 나는이 제대로하고있어 확인하고 싶습니다 :컨테이너에 요소를 추가하는 올바른 방법입니까?

vector<Mat> 
VideoHash::dct3d(vector<Mat> cube) 
{ 
    vector<Mat> dctPlanes; 
    for (int k = 0; k < TEMPORAL_DIM; ++k) 
    { 
     Mat spatial; 
     Mat freq; 
     cube[k].convertTo(spatial, CV_64F); 
     dct(spatial, freq); 
     dctPlanes.push_back(freq); 
    } 

    // Do other stuff here 
} 

나는 함수에 대한 입력으로 행렬의 벡터를 가지고있다. 벡터의 각 행렬에 대해 다른 데이터 유형 (double)으로 변환하고 변환 결과에 DCT를 수행 한 다음 DCT 결과를 다른 벡터에 저장합니다.

이게 맞습니까? for 루프 내부에서 생성되는 행렬에 대한 의문을 가지고 있습니다. 루프가 종료되면 범위를 벗어납니다. 스택의 해당 행렬에 할당 된 메모리는 어떻게됩니까? 루프 이후에도 계속 메모리에 액세스 할 수 있습니까 (예 : '여기 다른 항목 수행'섹션).

답변

5

행렬을 벡터로 푸시 백하면 vector로 할당 된 메모리에 값으로 복사됩니다. dctPlanes가 존재하는 한, 그것의 행렬은 여전히 ​​존재할 것입니다. 임시 변수 (공간, 주파수)는 루프 반복마다 범위를 벗어납니다.

편집 :

VideoHash::dct3d(vector<Mat> & cube) 
{ 
    Mat spatial; 
    vector<Mat> dctPlanes; 
    dctPlanes.resize(TEMPORAL_DIM); 
    for (int k = 0; k < TEMPORAL_DIM; ++k) 
    { 
     cube[k].convertTo(spatial, CV_64F); 
     dct(spatial, dctPlanes[k]); 
    } 

    // Do other stuff here 
} 

이상적으로 당신이 그 생성자의 모든 전화 비용을 피하기 싶어 이후, 당신은 벡터 완벽하지 크기를 조정할 때 : 최적화 문제를 해결하기 위해, 당신은 이런 식으로 뭔가에 대해 생각 - 그리고 그 주위에 방법이 있습니다 - 그러나 이것은 당신에게 원래의 코드에 비해 상당한 이익을 얻을 것입니다.

0

dctPlanes.push_back(freq)복사 임시 매트릭스 freq을 컨테이너에 넣습니다. Mat에 올바른 복사 생성자가있는 경우 컨테이너를 통해 데이터에 계속 액세스 할 수 있습니다. 분명히 freqspatial 자체는 각 반복의 끝에서 파괴되어 직접 액세스 할 수 없습니다. 자체가 이전도 무효로,이 선 후

dctPlanes.push_back(std::move(freq))

freq을 : 효율성이 필요한 경우

, 당신은 사용 후 매트를위한 C++ (11) 이동 생성자를 구현하고 고려할 수 있습니다 루프 범위 끝 - 이 컨테이너로으로 이동되었습니다.

+0

성능 문제와 관련하여 추가하고 싶습니다. 이동 생성자는 Mat 클래스가 동적으로 메모리를 할당하는 경우에만 성능을 향상시킵니다. 이 작업을 수행하는 행렬 클래스를 기억하지 못하기 때문에 성능 향상에 도움이 될 수 있습니다. 행렬 클래스의 경우 일반적으로 이동 생성자를 구현하는 의미있는 방법이 없습니다. – mbgda

+0

행렬이 임의의 차원 인 경우 일반적으로'size' 필드와 행렬에 동적으로 할당 된 내용에 대한 포인터가 있습니다. 이동 생성자는 얕은 스왑을 수행합니다. DCT는 일반적으로 큰 행렬 (예 : 이미지)에서 이루어지기 때문에이 특별한 경우에는 실제로 그럴 것이라고 기대합니다. – CygnusX1

+0

아, 아주 좋은 지적입니다. 나는 단순한 매트릭스가 아니라는 사실을 완전히 읽었습니다. 이 경우 성능이 확실히 향상됩니다. – mbgda

관련 문제