简单:cvLoadImage()
顾名思义,将整个图像加载到内存(考虑一个 10MB 文件)并返回一个IplImage*
说明图像数据在内存中的位置。
这非常有用,因为如果它返回一个IplImage
而不是,我们的应用程序将需要分配另外 10MB 的内存,复制程序内存中的数据!所以返回一个带有数据内存地址的指针实际上是一个非常聪明的设计决策。
cvReleaseImage()
接收一个双指针来反映这种设计。如果您下载 OpenCV v2.3 源代码,您可以在以下位置看到它的实现modules/core/src/array.cpp
:
2979 CV_IMPL void
2980 cvReleaseImage( IplImage ** image )
2981 {
2982 if( !image )
2983 CV_Error( CV_StsNullPtr, "" );
2984
2985 if( *image )
2986 {
2987 IplImage* img = *image;
2988 *image = 0;
2989
2990 cvReleaseData( img );
2991 cvReleaseImageHeader( &img );
2992 }
2993 }
很明显,内存资源的实际释放是由其他 2 个辅助函数完成的,它们在某些时候会调用cvFree()
以释放内存。
cvReleaseImage()
不过,@Nikolai 共享的简化是正确的。
编辑:回答您的评论。
分配一个指针0
永远不会释放malloc()
/保留的内存new
,它只会使指针指向其他地方,在这种情况下,无处可去!让我们明白什么cvReleaseImage (&img)
意思。这一切都始于:
IplImage* img = NULL;
指针声明与常规变量声明的作用相同:它分配一定数量的内存来存储一些数据。像上面这样的指针声明(在 32 位拱形中)分配 4 个字节的内存来存储其他变量的地址。换句话说,指针本身在它被声明的函数中消耗了 4 个字节的内存。
调用cvReleaseImage(&img)
传递指针的地址,而不是它指向的数据的地址(A-HA 时刻就在这里)。
现在,让我们分析剩下的代码:
2985 if( *image ) // does the original pointer points somewhere?
2986 {
// img copies the address of the data pointed by it's cousing image
2987 IplImage* img = *image;
// and handles the deallocation procedure from now own using img.
// By clearing the original pointer,
2988 *image = 0;
// OpenCV allows us to test for it's release
// after cvReleaseImage() executes.
2989
2990 cvReleaseData( img );
2991 cvReleaseImageHeader( &img );
2992 }
这样做*image = 0;
只是标准程序,所以稍后我们可以检查是否成功释放,如下所示:
cvReleaseImage (&img);
if (img != NULL)
{
// OOPS! Something went wrong, memory was not released!
}