C++动态内存申请

  1 //---------------------------------------//
  2 //----------动态内存申请---------//
  3 //
  4 // 包括指针申请,一位数组申请
  5 // 二维数组申请,内存连续和不连续的问题
  6 // 三维数组申请,内存连续和不连续的问题 
  7 //---------------------------------------//
  8 
  9 #include <iostream>
 10 using namespace std;
 11 
 12 int main() {
 13     //cout << sizeof(char) << "  " << sizeof(int) << "  " << sizeof(long) << "  " << sizeof(long long) << endl;
 14 
 15     //----------------- 单个数据申请 和 释放
 16 
 17     //int *p = (int*)malloc(sizeof(int));   //c语言的申请用法
 18     int *p1 = new int; //new + type 类型需要匹配
 19     int *p2 = new int(121); //初始化一个值
 20 
 21     *p1 = 12; //写入
 22     cout << *p1 << "  " << *p2 << endl; //读取
 23 
 24     delete p1; //delete+指针
 25     delete p2;
 26 
 27     //C++标准规定:delete空指针是合法的,没有副作用。
 28     //所以我们在Delete指针后赋值为NULL或0是个好习惯。对一个非空指针delete后,若没有赋NULL,若再次delete的话
 29     //有可能出现问题。如下代码:  
 30     p1 = NULL;          //如果把这句话注释掉,,不能运行,为了避免出现问题,指针被delete之后应该赋值NULL
 31     delete p1;
 32     //可以看出delete是释放指针指向的内存,并不是指针本身所占有的内存。所以delete后,指针的还是指向那块区域,并
 33     //未清0,所以如果下次用到,就会发生xxx空间不能访问的异常。以后delete后要赋值为空
 34 
 35     //------------------ 数组的申请和释放
 36 
 37     int *a = new int[5]; //申请数组
 38     memset(a, 0, 5 * sizeof(int)); //使用函数批量初始化 全称 memery set. c++没有提供数组初始化,可以用函数实现。
 39     //int *a1 = (int*)malloc(5*4); //c语言的的数组申请
 40 
 41     a[0] = 121;
 42     cout << a[0] << endl;
 43     delete[] a; //释放数组,对于标准语法而言,如果不匹配释放,结果是不确定的。
 44     a = NULL;
 45 
 46     //------------------ 二维数组[m*n]的申请和释放  ----  分配的内存不连续 -----
 47     int m = 5, n = 4;
 48     int **ta;
 49     //申请内存
 50     ta = new int*[m];
 51     for (int i = 0; i < m; i++) {
 52         ta[i] = new int[n];
 53     }
 54 
 55     //赋值
 56 
 57     // 不能用如下的初始化赋值,因为 ta 对应申请的语句是:  ta = new int*[m];
 58     //因此该数组存放的是指针地址[该地址为n个数的起始地址],并不是我们存放的数据
 59     //memset(ta,0,m*n*sizeof(int));         
 60 
 61     // 不能用如下的初始化赋值,因为 ta[0] 对应申请的语句是:  ta[i] = new int[n];   
 62     //因为每个n维数组申请的地址并不是连续的,因此不能简单的以ta[0]作为起始地址去赋值
 63     //memset(ta[0], 0, m*n * sizeof(int));           //
 64 
 65     //正确使用memset进行赋值
 66     for (int i = 0; i < m; i++) {
 67         memset(ta[i], 0, n * sizeof(int));
 68     }
 69 
 70     //或者按下标读取
 71     for (int i = 0; i < m; i++) {
 72         for (int j = 0; j < n; j++) 
 73             ta[i][j] = i * m + j;
 74     }
 75 
 76     //释放内存
 77     for (int i = 0; i < m; i++) {
 78         delete[] ta[i];
 79         ta[i] = NULL;
 80     }
 81     delete[] ta;
 82     ta = NULL;
 83 
 84 
 85     //------------------ 二维数组[m*n]的申请和释放  ----  分配的内存连续 ----- 这种和 定义变量时系统自动分配地址比较类似
 86     int **ta_l;
 87     //申请内存
 88     ta_l = new int*[m];
 89     //一次性分配所有的内存
 90     ta_l[0] = new int[m*n];
 91     //给每个地址进行赋值
 92     for (int i = 1; i < m; i++) {
 93         //不推荐用第一种方法进行指针地址的赋值,因为涉及到数据结构在内存中的存放问题,字节对齐以及CPU位数等
 94         //ta_l[i] = ta_l[i-1] + sizeof(int) * n ;       
 95         ta_l[i] = &(ta_l[0][i*n]);
 96     }
 97 
 98     //赋值
 99 
100     // 不能用如下的初始化赋值,因为 ta 对应申请的语句是:  ta = new int*[m];
101     //因此该数组存放的是指针地址[该地址为n个数的起始地址],并不是我们存放的数据
102     //memset(ta_l,0,m*n*sizeof(int));
103 
104     //因为内存连续,所以下面的方法可以用
105     memset(ta_l[0], 0, m*n * sizeof(int));           //
106 
107 
108     for (int i = 0; i < m; i++) {
109         memset(ta_l[i], 0, n * sizeof(int));
110     }
111     //或者按下标读取
112     for (int i = 0; i < m; i++) {
113         for (int j = 0; j < n; j++)
114             ta_l[i][j] = i * m + j;
115     }
116 
117     //释放内存
118 
119     //因为delete释放的时候要和new一一对应,因此不能用下面的释放方法
120     //for (int i = 0; i < m; i++) {
121     //    delete[] ta_l[i];
122     //    ta_l[i] = NULL;
123     //}
124     //正确方法如下:
125     delete[] ta_l[0];
126     for (int i = 0; i < m; i++) {
127         ta_l[i] = NULL;
128     }
129 
130     delete[] ta_l;
131     ta_l = NULL;
132 
133     //------------------ 三维数组[x*y*z]的申请和释放  ----  分配的内存不连续 -----
134     int x = 3, y = 4, z = 5;
135     int ***tha;
136     tha = new int **[x];        //申请用于存储二维数组指针
137     for (int i = 0; i < x; i++) {
138         tha[i] = new int *[y];  //申请用于存储一维数组指针
139         for (int j = 0; j < y; j++) {
140             tha[i][j] = new int[z];     //申请用于存放 【数据】  内存是不连续的
141         }
142     }
143 
144     //赋值
145 
146     //正确使用memset进行赋值
147     for (int i = 0; i < x; i++) {
148         for (int j = 0; j < y; j++) {
149             memset(tha[i][j], 0, z * sizeof(int));
150         } 
151     }
152 
153     //或者按下标读取
154     for (int i = 0; i < x; i++) {
155         for (int j = 0; j < y; j++) {
156             for (int q = 0; q < z; q++)
157                 tha[i][j][q] = (i * y + j) * z + q;
158         }
159     }
160 
161     //释放内存
162     for (int i = 0; i < x; i++) {
163         for (int j = 0; j < y; j++) {
164             delete[] tha[i][j];
165             tha[i][j] = NULL;
166         }
167         delete[] tha[i];
168         tha[i] = NULL;
169     }
170     delete[] tha;
171     tha = NULL;
172 
173 
174     //------------------ 三维数组[x*y*z]的申请和释放  ----  分配的内存连续 -----
175     tha = new int **[x];        //申请用于存储二维数组指针 
176 
177     tha[0] = new int *[x*y];  //申请用于存储一维数组指针 [连续的]
178     for (int i = 1; i < x; i++) {       //开始分配
179         tha[i] = &(tha[0][i*y]);
180     }
181 
182     tha[0][0] = new int[x*y*z];     // 申请用于存放 【数据】  [连续的]
183     for (int i = 0; i < x; i++) {   // 开始分配
184         for (int j = 0; j < y; j++) {
185             if (i == 0 && j == 0)
186                 continue;
187             tha[i][j] = &(tha[0][0][(i*y + j)*z]);
188         }
189     }
190 
191     //内存连续,可用如下赋值:
192     memset(tha[0][0], 0, x*y*z * sizeof(int));
193 
194     //正确使用memset进行赋值
195     for (int i = 0; i < x; i++) {
196         for (int j = 0; j < y; j++) {
197             memset(tha[i][j], 0, z * sizeof(int));
198         }
199     }
200 
201     //或者按下标读取
202     for (int i = 0; i < x; i++) {
203         for (int j = 0; j < y; j++) {
204             for (int q = 0; q < z; q++)
205                 tha[i][j][q] = (i * y + j) * z + q;
206         }
207     }
208 
209     //释放内存
210     delete[] tha[0][0];
211     delete[] tha[0];
212     delete[] tha;
213     tha = NULL;
214 
215     system("pause");
216     return 0;
217 }

 

posted @ 2019-11-09 16:34  博客园—哆啦A梦  阅读(1180)  评论(0)    收藏  举报