2013-03-11 4 views
1

Я не понимаю, почему я получаю поврежденную ошибку кучи с помощью этой программы (я использую OpenCV для класса Mat):Почему куча коррупции при возврате объекта Mat?

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(); 

I г ead, что возвращение копии объекта более элегантно на C++, чем ссылка. Поэтому я хотел бы знать, что не так.

EDIT: Visual studio разбивается на a->decode(vect), но это происходит только тогда, когда я возвращаю объект, а не ссылку.

EDIT 2: Я отредактировал код, чтобы отразить всю программу. Я думаю, проблема возникает из общего объекта a, который копируется и модифицируется одновременно. Я увижу, если проблема все еще происходит с использованием мьютекса.

+0

Возьмите 'vector ' по ссылке или const-ссылке. – Ajay

+0

@ Ajay У меня все еще есть ошибка.Передача по ссылке избегает копирования, но она удаляется в конце 'decode', правильно? – Seltymar

+0

Это не ответ, но рекомендация. – Ajay

ответ

1

Конструктор копирования cv::Mat не создает глубокую копию изображения. Он просто создает ссылку на оригинал Mat и увеличивает его счетчик ссылок. В следующей функции класса, return оператор вызывает конструктор копирования, возвращая ссылку на исходный image, который является вероятной причиной кучи коррупции:

Mat get_image(){ return image; } 

Вы должны вернуть глубокую копию 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. Вам нужно использовать библиотеку блокировки чтения/записи, которая не изгоняет читателей.

Альтернативно вы можете работать с мьютексами/критическими разделами. Оба цикла записи и чтение (get_image) получают эксклюзивный доступ к изображению, пока они выполняют свою работу.

Мне любопытно, хотя - ваша процедура потока декодирует вещи в бесконечном цикле. Что вы пытаетесь сделать там? И при чтении какого изображения вы ожидаете? Любое изображение в этот момент времени в итерации цикла?

+0

Я хочу использовать mutex из C++ 11, но он не реализован в vs2010 ... (Возможно, я собираюсь использовать boost). Фактически, часть, где я получаю данные и инициализирую свой вектор, является сетевой частью. У меня есть основной поток для пользовательского интерфейса и один для сети. У меня есть несколько решений, таких как использование асинхронизированных или неблокирующих сокетов. Я не уверен, что использовал лучший. – Seltymar

+0

с каких пор мьютексы уходят от разработки окон? Конечно, последние версии VS могут затруднить использование собственной библиотеки win, но они все еще существуют. http://msdn.microsoft.com/en-us/library/windows/desktop/ms686927%28v=vs.85%29.aspx И как я уже сказал, лучше всего использовать класс, который реализует чтение и запись замки. Джеффри Рихтер, парень, который писал книги по программированию окон, уже один год. http://www.dcs.ed.ac.uk/home/slip0102A/people/jcxb/code/SWMRG_8cpp-source.html – Amit

+0

Я пробовал с мьютексом, но у меня все еще есть проблема. Что указывает @ sgar91 в комментариях. Я жду от него, чтобы получить больше объяснений. – Seltymar

Смежные вопросы