// // // // // // // // //
///2012.12.5
// // // // // // // // //
手动分配内存的两个函数malloc与Calloc 的区别:
malloc全称是:Memory Allocation.
calloc全称是:Clear Allocation
名字就已经很清楚的说明了:
malloc只是开辟内存,但是里面的数据全是junk。
calloc开辟内存之后,还要进行clear,将其清零。
大家注意,
声明数组指针空间的时候,
最好使用calloc,
因为我们需要判断当前指针位置是否存在数据,
而存在数据的证据就是其数据不为0。
当然,
二者的使用方法也有些许不同,
malloc只需要传入一个参数就可以了:总大小。
calloc需要传入两个参数:类型的单位长度以及总数目。
当然,
这一切都要配合sizeof来进行地址分配的。
示例:
array = (int*)malloc(sizeof(int) * 10);
array = (int*)calloc(10,sizeof(int));
// // // // // // // // //
///2012.12.6
// // // // // // // // //
今天我们来讲一下第三个分配动态数组的方法:new
这个是大家最为熟悉的方法了,
相比之下,
new 与malloc的相似度是最高的:
两者都是开辟一个所需数组的总大小地址,
今天我们来讲一下第三个分配动态数组的方法:new
这个是大家最为熟悉的方法了,
相比之下,
new 与malloc的相似度是最高的:
两者都是开辟一个所需数组的总大小地址。
不过还是有几点不同的:
1.new不需要使用sizeof之类的来指定大小。
2.new开辟的时候会调用构造函数,而malloc 不会(依旧保持junk数据)。
这一点看大家怎么使用了,
如果是int之流的动态数组这一点其实是无关乎效率高低的。
不过new在对数组其实有一个独特的地方,
就是new会对每一个数组元素都调用构造函数,
这是一把双刃剑,
虽然使数组"更具价值"了,
但是与不会为每个元素调用构造函数的mallioc相比,
速度自然要低一些。
3.new在出现异常的时候(比如说内存不够了)会抛出一个bad_malloc异常,
而malloc则只会return 0.
当然,
c++标准是这么说的,
但每个编译器并没有遵守这个标准:
比如说MSVC6中,遇到new错误时也是return 0
不过瑕不掩瑜,
这是一个安全的机制,
毕竟异常对于程序的强健性是非常必要的。
总的来说,
还是推荐大家使用new来为动态数组分配内存(当然大家也是这么做的。。。)
最后,
同样是其示例用法:
int* array;
array = new int[10];
// // // // // // // // //
///2012.12.8
// // // // // // // // //
这次来讲讲free 与delete 的区别:
这两个都是用来释放动态数组的,
但是在用法及原理上有些许不同。
如果用离散来进行类比的话,
free是与calloc,malloc构成满射关系的,
delete是与new构成双射关系。
free主要作用是释放一段内存,
但是,
请注意,
它只是释放,
只是将这段内存标记为可用状态(同未开辟这段内存时的状态相同),
然而,
数组指针却并未发生改变,
只不过里面的数据又是一堆junk了。
为了避免这种情况发生,
我们最好将动态数组在被free之后,
手动赋值为零,
free(array);
array = 0;
相比之下,
delete就安全许多,
不过要注意,
delete要加上[]:
delete[] array;
如果不加中括号的话,
就是删除array的第一个元素,
这种做法会造成内存溢出。
delete的原理是调用array类型自身的析构函数,
这样是一个很好的做法(正因如此,才说其与new构成双射)。
不过,
按照一般编程习惯,
同样在调用delete之后手动将数组赋值为0。
// // // // // // // // //
///2012.12.10
// // // // // // // // //
接下来我们讲一下如何对一个动态数组进行ReSize(重塑大小)。
有两个办法,
第一个是使用realloc方法,
这个方法与malloc相对应,
示例如下:
int* array = (int*)malloc(10* sizeof(int));
int* temp = array;
array = (int*)realloc(array,20 * sizeof(int));
这个办法最大的优势是——速度。
如果重塑的数组大小大于原数组的话,
甚至不会产生任何新的数组,
只是将指针指向重塑之后的数组位置而已。
不过自然是有弊端的,
就是如果重塑的数组大小小于原有数组大小的话,
那么将会失去后面二者之差个的数据。
而另一种方法,
大家可以先思考一下,
明天我再将答案揭晓。
// // // // // // // // //
///2012.12.15
// // // // // // // // //
接着上一次的内容讲,其实resize一个动态数组的第二个办法就是大家熟知的new
int* array = 0; int* temp = 0; int index; array = new int[10]; temp = new int[20]; for(index = 0;index < 10;index++) temp[index] = array[index]; delete[] array; array = temp; temp = 0 ;
// // // // // // // // //
///2012.12.10
// // // // // // // // //