【2012.12.5】C++ Notifications

来源:互联网 发布:上众划算淘宝会不会查 编辑:程序博客网 时间:2024/05/17 01:38

// // // // // // // // //

///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

// // // // // // // // //



原创粉丝点击