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 }
记录每天生活的点点滴滴,呵呵呵呵呵呵

浙公网安备 33010602011771号