2012-02-05 4 views
4

Я пытаюсь скопировать данные указателей на другой указатель, так что, если я его изменю, значение в другом не изменится.Как сделать копию указателя

Мне нужно это, потому что я кодирую цикл, где у меня есть два указателя на структуру, значение и lastValue. На каждой итерации цикла присваиваю value контент lastValue, и я заполняю value новым контентом. Проблема в том, что, поскольку оба являются указателями на структуру, когда я меняю value, также меняются изменения lastValue, и это не то поведение, которое я хочу. Код будет что-то вроде этого (в структуры являются IplImages из OpenCV):

IplImage *value; 
Iplimage *lastValue; 
while(1) 
{ 
    lastValue=value; 
    value=cvQueryFrame(capture);//This fills the struct with new information 
} 

Это будет работать, если они где нормальные структур, а потому, что они являются указателями, и в конечном итоге с тем же значением. Есть ли способ получить копию указателя с тем же значением, но с другим адресом?

+0

'Cv :: Mat' предоставляет' клон() 'метод – Vyktor

ответ

1

Функция cvQueryFrame захватывает кадр из камеры или видеофайла , распаковывает и возвращает его. Он возвращает указатель на внутренний буфер OpenCV, имеющий последний захваченный кадр. Это должно быть причиной того, что вы получаете одинаковое значение. Если вам нужны 2 кадра, вы должны создать копию изображения.

IplImage * previousFrame, *currentFrame ; 
CvCapture* video = cvCaptureFromAVI("video.avi"); 
currentFrame = cvQueryFrame(video); 

// COPY IMAGE 
previousFrame = cvCloneImage(currentFrame); 

while(currentFrame = cvQueryFrame(video)) 
{ 
    //... 
    cvCopy(currentFrame , previousFrame); 
} 
//... 
2
value=cvQueryFrame(capture); 

при изменении значения, LastValue меняется слишком

Нет, это не так. Указатель value будет перезаписан, как вам хочется. Эта строка кода не может влиять на lastValue.

а потому, что они являются указателями, и в конечном итоге с тем же значением

Нет, это не имеет значения, что они являются указателями. Указатели по-прежнему являются объектами сами по себе.


Однако, cvQueryFrame возвращает указатель на буфер, который you shall not modify or free как это делается для вас:

Обратите внимание, что изображение, захваченное устройством выделяется/освобожден с помощью функции захвата. Нет необходимости публиковать его явно.

Хотя the documentation немного неясно, кажется вероятным, что буфер действует только до следующего вызова cvQueryFrame (который будет затем повторно использовать выделенную память). Так что хотя lastValue не может и не измениться, это происходит, чтобы в конечном итоге указывать на новую рамку.

Чтобы обойти эту проблему, вы можете явно скопировать объект, который lastValue указывает на:

lastValue = cvCloneImage(value); 

Теперь вы, вероятно, взять на себя ответственность за освобождение его (но опять-таки это не совсем понятно из моего беглого взгляда на документация):

cvReleaseImage(&lastValue); 
+0

О хорошо, я учил LastValue также изменилось, потому что LastValue == значение решает верно, если я проверить его на конец цикла. Я все еще новичок в OpenCV, и я не совсем понял, почему lastvalue заканчивается тем же значением ценности, но я буду использовать cvCloneImage(), чтобы обойти проблему. Большое вам спасибо – XaitormanX

+0

@ user1190588: Тогда так получилось, что по дизайну 'cvQueryFrame' для видеокадра используется та же область памяти. :) 'lastValue' не изменен _not_, но это не обязательно, потому что место, на которое оно указывает, является тем же самым расположением данных _new_ frame. –

+0

Спасибо, я понимаю это сейчас. cvCloneImage отлично работает, но если я использую cvReleaseImage (& lastValue), программа выйдет из строя, поэтому я полагаю, что нет необходимости вручную выводить изображение. – XaitormanX

0

Похоже, вы поступаете правильно.

last_value = value; //copy pointer 

но это не совсем то, что вы хотите, потому что это не указатель, который вы хотите скопировать, это данные внутри.поэтому старый указатель обновляется вместе с новым указателем. Я думаю, что вам нужна копия самой структуры.

Если указатель указывает на какой-то класс, который вы пишете, добавить метод конструктор копирования на него, а затем скопировать значение указателя так:

last_value = new MyClass(*value); //construct object, copy from what value points to 
//change value 
+0

Старый указатель не обновляется вообще. И он не владеет классом. В противном случае правильно. –

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