前言
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);