C++ 指针的malloc、memcpy和 free

前言

malloc和free必须成双成对的出现,一般给对象malloc了内存空间,memcpy内存拷贝向空间中写内容,最后待空间使用结束后务必free掉分配的空间,否则会出现内存leak。让程序员们头疼的一般是一维指针和二维指针的内存操作,下面一一解说。

1、一维指针的内存操作

一维指针相对来讲比较简单,比如给int指针开辟空间并写内容:

int c = 10;
	int *b = &c;
	int *a;
	a = (int*)malloc(sizeof(int));
	memcpy(a,b,sizeof(int));
	cout<<*a<<endl;
	free(a);

同样的,给自定义类型的对象开辟内存空间,如下,给一副大小为mwidth*mheight的图片分配空间(T是像素存储类型):

template<typename T>
void unitTest<T>::getData(const char *path)
{
	CImg<T> reader; 
	reader.load_tiff(path); //for now, just load_tiff
	mwidth = reader._width;
	mheight = reader._height;
	mpImgbuffer = (T *)malloc(sizeof(T)*mwidth*mheight);
	memcpy(mpImgbuffer,reader._data,sizeof(T)*mwidth*mheight);
}


2、二维指针的内存操作

二维指针的内存操作才是迷之云雾。应该先给地址分配内存, 然后for循环给每个地址指向的内容分配空间;free空间的时候也是for循环一个个释放掉对象内容空间,最后释放掉地址空间。

这是一个简单int类型的二维指针空间操作

int b[100];
	for (int i = 0; i < 100; i++)
	{
		b[i] = 10;
	}
	int **a;

	a = (int**)malloc(sizeof(int*)* 100);//给地址分配空间

	for (int i = 0; i < 100; i++)
	{
		a[i] = (int*)malloc(sizeof(int));//给每个地址指向的内容分配空间
		memcpy(a[i], b, sizeof(int));

	}

	for (int i = 0; i < 100; i++)
	{
		cout << *(*(a + i)) << endl;
	}
	for (int i = 0; i < 100; i++)
	{
		free(a[i]);
	}
	free(a);

同样的,给自定义类型的二维指针开辟内存空间,


template<typename T>
void unitTest<T>::getDataFiles(const char *path, u32 repcount)
{
	CImg<T> reader;	
	getFiles(path, mvImgFiles);//char * > string
	miImgNum = mvImgFiles.size();
	reader.load_tiff(mvImgFiles[0].c_str()); //for now, just load_tiff
	mwidth = reader._width;
	mheight = reader._height;
	mppImgArray = (u8 **)malloc(sizeof(u8*)*miImgNum*repcount);//分配miImgNum个u8*的地址

	for(int i = 0 ; i < miImgNum; i++)
	{
		for(int j = 0; j < repcount; j++)
		{
			reader.load_tiff(mvImgFiles[i].c_str());
		        mppImgArray[i*repcount +j]= (u8*)malloc(sizeof(u8)*mwidth*mheight*2);//每个u8*的地址指向的对象分配一副图片大小的内存空间
			memcpy(mppImgArray[i*repcount +j],(u8 *)reader._data,sizeof(u8)*mwidth*mheight);//
		}
	}
}

释放空间操作:

for(int i = 0; i < miImgNum; i++)
	{
		free(mppImgArray[i]);
	}
	free(mppImgArray);

note: 这边有一个不成文的坑,如果工程不大,开辟空间的开销可以接受,那么以防内存空间分配不够,可以给足够的空间,反正最后都会free掉

【一般编译或者执行的时候报错access violation 然后break掉,一般都是内存空间分配不够】

比如,就这个例子,分配的对象类型时u8**类型的,当图片的像素类型是u8类型时,

mppImgArray[i*repcount +j]= (u8*)malloc(sizeof(u8)*mwidth*mheight);
这样分配内存不多不少,当图片的像素类型是u16类型时,这样分配就要报access violation的错了,因为u16比u8多占一个字节,因此宁愿当碰到u8的图片时,我分配的内存多那么点,也不想让程序挂掉,应该改为:

mppImgArray[i*repcount +j]= (u8*)malloc(sizeof(u8)*mwidth*mheight*2);



猜你喜欢

转载自blog.csdn.net/liu1152239/article/details/72454326