2013-03-11 3 views
1

나는 (I 클래스 Mat에 대한 OpenCV의를 사용하고 있습니다)이 프로그램 손상된 힙 오류가 왜 이해가 안가 :왜 개체를 반환 할 때 힙 손상이 발생합니까?

class A { 
    private: 
    Mat image;  

    static UINT ThreadProc(LPVOID pParam) { 
     A* pThis= (ClientNetwork*)pParam; 
     UINT nRet= pThis->DoThreadProc();  // get out of 'static mode' 
     return(nRet); 
    } 
    UINT ClientNetwork::DoThreadProc() { 
     vector<uchar> vect; 
     while(1) { 
      /**** initialize vect and get the image data to decode ****/ 

      decode(vect); 
     } 
    } 

    public: 
    void decode(const vector<uchar>& vectorData){image=imdecode(vectorData, CV_LOAD_IMAGE_COLOR);} 
    Mat get_image(){return image;} 
    void start() {m_pcThread= AfxBeginThread(ThreadProc, this);} 
} 

int main() { 
    A* a = new A(); 
    a->start(); 
    while(1) { 
     Mat image = a->get_image(); 
    } 
    delete a; 
    return 0; 
} 

내가 참조를 반환하는 경우 때문에 오류가 Mat image = a->get_image();에서 온 것 같다 대신 객체의 복사본, 나는 더 이상 오류가 없습니다 :

Mat* get_image(){return &image;} 

Mat* image = a->get_image(); 

내가 r에 객체의 복사본을 반환하는 것은 참조보다는 C++에서 더 우아합니다. 그래서 나는 무엇이 잘못되었는지 알고 싶다.

EDIT : Visual Studio는 a->decode(vect)에 나옵니다.하지만 객체가 아닌 참조가 반환 될 때만 발생합니다.

편집 2 : 전체 프로그램을 반영하도록 코드를 편집했습니다. 나는 문제가 복사 및 수정 동시에 공유 객체 a에서 온 것 같아요. 뮤텍스를 사용하여 문제가 계속 발생하는지 확인할 수 있습니다.

+0

'벡터 '을 참조 또는 const 참조로 가져옵니다. – Ajay

+0

@Ajay 오류가 있습니다.참조로 전달하면 복사본을 피할 수 있지만'decode'의 끝에서 삭제됩니다. 맞습니까? – Seltymar

+0

그 대답은 아니지만, 추천했다. – Ajay

답변

1

복사 생성자 cv::Mat은 이미지의 전체 복사본을 만들지 않습니다. 단지 원래의 Mat에 대한 참조를 만들고 참조 카운트를 증가시킵니다.

Mat get_image(){ return image; } 

당신은 image의 깊은 사본을 반환해야합니다 : 클래스의 다음 함수에서 는 return 문은 가능한 힙 손상의 원인이 원래 image에 대한 참조를 반환, 복사 생성자를 호출 다음과 같이 원래 image이 실수로 수정되지 않도록합니다.

Mat get_image(){ return image.clone(); } 
2

초기화하지 않고 a을 사용합니다.

int main() { 
    A* a; 
    vector<uchar> vect; 
    while(1) { 
     // get the vector of data 
     a->decode(vect); 

인구 : 당신.

더 나은 결과를 얻으려면 a을 초기화하십시오.

+0

나쁘다, 지금 바로 잡는다. 오브젝트를 반환하기 때문에 힙 손상이 발생하는 이유입니다. – Seltymar

2

다음은 사용자가 제안한 스레드 동기화 문제입니다. 무한 while 루프에서 이미지가 끊임없이 채워집니다. 그리고 어딘가에서 그것의 사본을 만들려고 노력합니다. 재해를위한 조리법. 각 반복에서 DoThreadProc의 루프 내에서 쓰기 잠금을 수행해야합니다. 그런 다음 get_image 내부에서 읽기 잠금을 수행해야합니다. 독자를 굶주 리지 않는 읽기/쓰기 잠금 라이브러리를 사용해야합니다.

또는 mutexes/critical 섹션으로 작업 할 수도 있습니다. 둘 다 루프를 작성하고 읽기 (get_image)는 작업을 수행하는 동안 이미지에 독점적으로 액세스합니다.

나는 궁금해. 스레드 프로 시저가 무한 루프에서 물건을 해독하는 것입니다. 거기서 뭘 하려구? 그리고 어떤 이미지를 읽는 동안 당신은 기대합니까? 루프 반복에서 그 시점의 모든 이미지?

+0

C++ 11에서 뮤텍스를 사용하고 싶지만 vs2010에서는 구현되지 않습니다 ... (아마도 부스트를 사용할 것입니다.) 사실, 데이터를 얻고 벡터를 초기화하는 부분은 네트워크 부분입니다. UI 용 주 스레드와 네트워크 용 주 스레드가 있습니다. 비동기 또는 비 차단 소켓을 사용하는 것과 같은 여러 가지 솔루션이 있습니다. 나는 가장 좋은 것을 사용했는지 확신 할 수 없다. – Seltymar

+0

mutexes가 Windows 개발에서 언제 사라 졌나요? VS의 최신 버전이 네이티브 win 라이브러리를 사용하는 것을 더 어렵게 만들 수도 있지만 여전히 존재합니다. http://msdn.microsoft.com/en-us/library/windows/desktop/ms686927%28v=vs.85%29.aspx 그리고 내가 말했듯이, 읽기 및 쓰기를 구현하는 클래스를 사용하는 것이 가장 좋습니다 자물쇠. 제프리 리히터 (Jeffery Richter)는 Windows 프로그래밍 서적을 저술 한 사람입니다. http://www.dcs.ed.ac.uk/home/slip0102A/people/jcxb/code/SWMRG_8cpp-source.html – Amit

+0

뮤텍스를 사용해 보았지만 여전히 문제가 있습니다. @ sgar91이 주석문에서 지적한 것은 무엇인가? 나는 그에게서 더 많은 설명을 얻기를 기다리고있다. – Seltymar

관련 문제