动态分配内存 and malloc&new and 数组的动态分配、初始化(memset)和撤销(delete)

来源:互联网 发布:java socket建立长连接 编辑:程序博客网 时间:2024/04/30 15:38
 

在计算机的系统中有四个内存区域:
1)栈:在栈里面存储一些我们定义的局部变量和形参。
2)字符常量区:主要存储一些字符常量,比如:char *p_str="cat",其中"cat"就存储于字符常量区里。
3)全局区:在全局区里储存一些全局变量和静态变量
4)堆:主要是通过动态分配的储存空间,即动态分配内存空间。

栈是线程相关的 一个线程会建立一个栈,函数中的局部变量 实际上是在栈里面的 函数返回后 就从栈中pop出来,栈的容量是有限的 超过一定大小就栈就会击穿了,比如你写了深层次的递归,然后再函数中使用大量的数组,很容易就击穿了
堆是动态存储空间,一个进程默认只有一个堆,进程中所有的线程都共享这个堆的空间,所以你在一个线程中从堆中分配内存,再另一个线程中也可以访问,同时堆也更容易扩展和交换数据

为什么要动态分配内存?
一是受栈空间的限制,二是不想浪费内存。

动态分配和静态分配的比较:
动态分配就是基于现实考虑,在需要时才分配你需要数量的内存(当然你申请的内存什么时候用完,只有你才知道,系统不会浪费时间给你猜的)。
一般的静态变量都是放在栈里(按顺序排列好,访问也最快,当然在回收前是不能改变顺序和已分配的数量的,作用域结束就回收),受栈的限制。

 

malloc 和  new

1)new 是c++中的操作符,malloc是c 中的一个函数

2)new 不止是分配内存,而且会调用类的构造函数,同理delete会调用类的析

构函数,而malloc则只分配内存,不会进行初始化类成员的工作,同样free也不

会调用析构函数

3)内存泄漏对于malloc或者new都可以检查出来的,区别在于new可以指明是那

个文件的那一行,而malloc没有这些信息

4)new 和 malloc效率比较
new 有三个字母, malloc有六个字母
new可以认为是malloc加构造函数的执行。
new出来的指针是直接带类型信息的。
而malloc返回的都是void指针

 

数组的动态分配(new)、初始化(memset)和撤销(delete)

一维数组:
malloc的例子:
int* pB2 = (int*)malloc(20 * sizeof(int));
if(pB2 == NULL) return 0;
memset(pB2,-1,20 * sizeof(CvBlob)); //初始化为-1
/**************/
if(pB2)
{
 free(pB2);
 pB2 = NULL;
}

new 的例子:
int* pB2 = new int[20];
/****************/
delete []pB2;
pB2 = NULL;

二维数组:
二维数组(n行m列)利用new来进行动态分配实际上相当于对n个m元数组进行动态

分配。

int **array;

array=new int *[10];

for(int i=0;i<10;i++)

         array[i]=new int [5];

上面的操作完成了一个10行5列的二维数组array[10][5]的动态分配,可以看到

我们先动态分配一个10单元的数组的指针的指针的首地址给**array,然后再对

其每个首地址进行遍历,同时完成一个5单元的数组的动态分配,并把首地址给

array[i],从而完成了二维数组array[10][5]的动态分配。
   因为memset只能完成一个一维数组的初始化,因此最好的办法就是和二维数

组的动态分配结合起来,new一个,memset一个。

int **array;
array = new int[10];
for(int i=0;i<10;i++)
{
 array[i] = new int[5];
 memset(array,0,5*sizeof(int));
}

二维数组的撤销

for(int i=0;i<10;i++)
{
 delete []array[i];
}
delete []array;

三维数组用一个例子说明:

 

#include <stdio.h>

#include <memory.h>

#define size1 5

#define size2 10

#define size3 15

 

int main()

{

       int *** arr;

       int i,j,k;

       /////////////////// 动态开辟 相当于arr[size1][size2][size3]

       arr = new int**[size1];

       for (i = 0; i < size1; i ++) {

              arr[i] = new int*[size2];

              for (j = 0; j < size2; j ++) {

                     arr[i][j] = new int[size3];

              }

       }

       /////////////////// 用for循环初始化

       for (i = 0; i < size1; i ++) {

              for (j = 0; j < size2; j ++) {

                     for (k = 0; k < size3; k ++) {

                            arr[i][j][k] = i * j * k;

                     }

              }

       }

       for (i = 0; i < size1; i ++) {

              for (j = 0; j < size2; j ++) {

                     for (k = 0; k < size3; k ++) {

                            printf("i*j*k=%d*%d*%d=

%d/n",i,j,k,arr[i][j][k]);

                     }

              }

       }

       /////////////////// 用memset,如果是静态int arr[][][]的话,

直接memset(arr,0,sizeof(arr));数组初始化为0

 

       for (i = 0; i < size1; i ++) {

              for (j = 0; j < size2; j ++) {

                     memset(arr[i][j],-1,sizeof(int) * size3);

              }

       }

 

       for (i = 0; i < size1; i ++) {

              for (j = 0; j < size2; j ++) {

                     for (k = 0; k < size3; k ++) {

                            printf("i,j,k=%d,%d,%d=

%d/n",i,j,k,arr[i][j][k]);

                     }

              }

       }

 

       ///////////////////// 释放内存

       for (i = 0; i < size1; i ++) {

              for (j = 0; j < size2; j ++) {

                     delete[] arr[i][j];

              }

              delete[] arr[i];

       }

       delete[] arr;

       return 0;

}


 

原创粉丝点击