2014-04-11 3 views
0

내가 삭제 촉진하기 위하여 나는 매트 소멸자를 호출하는 업데이트하도록 조언했다 매트에 대한 포인터를 삭제하려면이 기능을 가지고 :어떻게 ~ 매트 매트 소멸자에 대한 포인터에 삭제 부를 것이다()

void cv_x_Mat(void* ptr) { 
     delete (Mat*)ptr; 
    } 

이것은 컴파일하는 것처럼 보이지 않지만 오류를 게시하지 않았습니다. 왜냐하면 누군가가 소멸자에 익숙한 오류를 볼 수있을 것이라고 생각했기 때문입니다. 어떤 도움을 주셔서 감사합니다.

void cv_x_Mat(void* ptr) { 
     Mat::~Mat() {delete ptr;}; 
    } 
+0

두 번째 것은 정의 *입니다. 코드가 호출되지 않습니다. 정확하게 # 1 아이디어가 잘못 되었습니까? – berak

+0

@berak 나는 삭제를 수행하기 위해 매트 소멸자에게 전화해야한다고 들었는데, 제 코드는 동료가 보았고 그게 더 낫다는 말을했습니다 ... 내 게시물에 답해 주셔서 감사합니다. – user3517736

+0

@berak, 제게 보여 주 시겠어요? 소멸자에 대한 삭제를 호출하는 방법, 나는 그것이 내 프로젝트에 대한 필요하다고 들었다. – user3517736

답변

1

담당자가 없기 때문에 의견을 말할 수 없습니다. 그러나 저는 user3517736이 (를) 참조하는 동료입니다. 우리는 OpenCV 바인딩을 다른 언어로 작업 중이므로 언어 ​​경계를 넘나 드는 어려운 메모리 관리 문제를 다루고 있습니다.

내가 제안한 바에 따르면 그가 정확히 제안한 것이 었습니다.

extern "C" void cv_delete_Mat(Mat* self) { 
    delete self; 
} 

: 나는 그가 그렇게처럼 매트 포인터에 삭제 호출하는 통근자 "C"기능을 전달한다 할 필요가 그래서 뭐, 그 자료가 소멸자에서 호출 할 것이라는 가정 (지금 확인)에서 있었다 적절한 C interop (user3517736의 경우에는 Common Lisp)을 사용하여 대상 언어의 가비지 컬렉터에 객체의 finalizer로 전달합니다.

하스켈 (내 대상)에서 이것은 포인터를 ForeignPtr로 취급하고 명시 적으로 cv_Mat_delete를 호출하는 finalizer로 포인터를 구성한다는 것을 의미합니다. 나는 누군가가 호기심이 있다면 이것을 확장 할 수 있습니다.

C interop 및 GC가있는 언어가 아마도 포인터를 사용하지 않고 새로운 것을 통해 초기화 된 개체에서 올바르지 않다고 설명하려고했기 때문에 혼란스러워 보였습니다. 이 문제는 finalizer가 무료 호출에 대한 선행 호출 될 수 있다는 점에서 더 복잡해졌습니다. 이는 분명히 문제가 있으며이 경우 정답은 소멸자 또는 Mat :: release()를 명시 적으로 호출하는 것입니다. 전자는 분명히 다른 OpenCV 유형에도 일반화되어 있습니다.

그래서 여기에 가장 FFIs 작업 할 가장 일반적인 솔루션, 그리고 아주 쉽게 다른 종류의 일반화 :

물론
extern "C" void cv_delete_Mat(Mat* self) { 
    self->~Mat(); 
} 

, 즉 여전히 잘못 확보 (암시)를 호출하지만 많지 않다 FFI 자체를 C++을 포함하도록 확장하지 않고도 그것에 대해 수행 할 수 있습니다.이 경우 모든 것이 어쨌든 논리적이지 않습니다.

OP의 질문과이 페이지의 후속 답변에 모두 답변이 되었기를 바랍니다.

3

당신은 무료로 행렬 메모리에 매트 :: 릴리스()를 사용할 수 있습니다

을 : 당신은 릴리스() CV : 매트 소멸자는 당신을 위해 그것을 할 것이기 때문에 생략도 할 수

cv::Mat *ptr = new cv::Mat(1000, 1000, CV_8UC3); 
ptr->setTo(cv::Scalar(255, 0, 0)); 
// some code 
ptr->release(); // DON'T release manually ptr->data 
delete ptr;  // this will call delete[] on ptr->data 

cv::Mat *ptr = new cv::Mat(1000, 1000, CV_8UC3); 
ptr->setTo(cv::Scalar(255, 0, 0)); 
// some code 
delete ptr;  // this will call delete[] on ptr->data 

Mat :: release는 삭제 안전합니다. 두 번하면 나쁜 결과를 초래하지 않습니다.