C++学习10:使用new分配内存
2017-08-16 23:09
141 查看
在C++中,可以沿用C中的malloc分配内存,也可以使用new运算符。今天就来学习使用new分配内存。
new的使用方法如下:
使用时用户需要指定类型(指针类型和要开辟的内存存储的数据类型),new可以自动找到一个正确长度的内存块,并返回内存块的地址。
比如:
这里指定了int型,new会自动找到适合存储int的内存,将地址返回赋给指针p。
此时,使用new开辟的内存块只能通过指针p来访问,这块内存是未命名的。
要注意一点:new分配的内存位于堆(heap)或自由存储区(free store)中,而常规变量分配的内存是在栈(stack)中。堆和栈的区别在于:栈(stack)由编译器自动分配释放,而堆(heap)一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。
在使用new时,释放内存的方法就是delete。
这样就可以释放掉通过new为开辟的内存了。
需要注意的是,delete只能释放由new开辟的内存。注意以下三种情况:
1、如果试图释放常规变量声明分配的内存,会报错。如:
2、如果试图释放已被delete释放的内存,会报错。如:
3、delete可以释放空指针,这是安全的,不报错。如:
如:
这里声明一个int型数组,长度为100,其内存空间在编译时已经分配好了。无论这个数组在实际运行中使用了多少,总是会占用那部分内存空间。
而如果使用new创建动态数组:
其内存是在运行时在分配的,当不使用时可以使用delete释放掉。释放动态数组时需要加[]:
如果不加[],但不会报错,结果是不确定的,不要这样做。
这里贴一个c++ primer plus中的一个例子,个人感觉十分巧妙。
可以看到,动态数组实际是在getname函数中建立的。通过临时字符数组temp存储输入的字符串,通过strlen(temp)+1计算需要的字符串长度提供给new,实现开辟对应大小的内存空间,并通过strcpy(pn, temp)将字符串复制到新开辟的内存处。
这样做可以每次都创建刚好能够存储输入字符串的内存块,在读取大量字符串的程序中,可以节省大量内存。
需要注意的是,这里new和delete放在了不同的函数中,这样是可以的,但容易忘记delete。
new的作用和使用方法:
new的作用在于可以在程序运行阶段动态分配内存,内存的大小在运行时根据需要确定,从而高效利用内存空间。new的使用方法如下:
typeName* pointer_name = new typeName
使用时用户需要指定类型(指针类型和要开辟的内存存储的数据类型),new可以自动找到一个正确长度的内存块,并返回内存块的地址。
比如:
int* p = new int;
这里指定了int型,new会自动找到适合存储int的内存,将地址返回赋给指针p。
此时,使用new开辟的内存块只能通过指针p来访问,这块内存是未命名的。
要注意一点:new分配的内存位于堆(heap)或自由存储区(free store)中,而常规变量分配的内存是在栈(stack)中。堆和栈的区别在于:栈(stack)由编译器自动分配释放,而堆(heap)一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。
在使用new时,释放内存的方法就是delete。
使用delete释放内存
delete可以释放内存供其他部分使用。方法十分简单,在delete后加指向待释放内存的指针即可,比如:int* p = new int; delete p;
这样就可以释放掉通过new为开辟的内存了。
需要注意的是,delete只能释放由new开辟的内存。注意以下三种情况:
1、如果试图释放常规变量声明分配的内存,会报错。如:
//delete不能释放常规变量声明分配的内存 int i =3; int* p = &i;
2、如果试图释放已被delete释放的内存,会报错。如:
//delete释放后,p指针不会被删除,而是重新指向了一处新的地址。 int* p = new int; delete p; delete p;
3、delete可以释放空指针,这是安全的,不报错。如:
int* p = NULL; delete p; delete p;
使用new创建动态数组
之前说了,new可以在运行时动态分配内存,这一作用的具体体现就是创建动态数组。如:
int data[100]={0};
这里声明一个int型数组,长度为100,其内存空间在编译时已经分配好了。无论这个数组在实际运行中使用了多少,总是会占用那部分内存空间。
而如果使用new创建动态数组:
int* p = new int [100]; //p指向动态数组的首地址
其内存是在运行时在分配的,当不使用时可以使用delete释放掉。释放动态数组时需要加[]:
int* p = new int [100]; delete [] p;
如果不加[],但不会报错,结果是不确定的,不要这样做。
这里贴一个c++ primer plus中的一个例子,个人感觉十分巧妙。
#include<iostream> #include<cstring> using namespace std; char* getname(void); int main(void) { char* name; name = getname(); cout << "The length of " << name << " is " << strlen(name) << endl; delete [] name; name = getname(); cout << "The length of " << name << " is " << strlen(name) << endl; delete [] name; system("pause"); } char* getname() { char temp[80]; cout << "Enter last name: "; cin >> temp; char* pn = new char[strlen(temp)+1]; strcpy(pn, temp); return pn; }
可以看到,动态数组实际是在getname函数中建立的。通过临时字符数组temp存储输入的字符串,通过strlen(temp)+1计算需要的字符串长度提供给new,实现开辟对应大小的内存空间,并通过strcpy(pn, temp)将字符串复制到新开辟的内存处。
这样做可以每次都创建刚好能够存储输入字符串的内存块,在读取大量字符串的程序中,可以节省大量内存。
需要注意的是,这里new和delete放在了不同的函数中,这样是可以的,但容易忘记delete。
相关文章推荐
- 学习参考资料:使用QT/C++为BlackBerry 10开发native应用
- C++学习笔记之1:使用相同形式的new和delete
- C++之父元旦专访(8+13个问题,关于C++的学习&使用和未来)
- SIP协议解析与实现(c和c++ 使用osip) 10
- Atlas学习手记(10):使用AlwaysVisibleControl Extender
- 学习使用资源文件[10] - 嵌入和提取任何类型的文件
- [收藏]C++ Tips(10)--宏的使用
- C++之父元旦专访(8+13个问题,关于C++的学习&使用和未来)(转帖)
- 学习 10 种良好的 XML 使用习惯
- 学习 10 种良好的 XML 使用习惯
- 学习 10 种良好的 XML 使用习惯
- 学习 10 种良好的 XML 使用习惯
- 学习 10 种良好的 XML 使用习惯
- Symbian学习笔记(10):使用ListBox
- Atlas学习手记(10):使用AlwaysVisibleControl Extender
- 《被误解的C++——学习和使用》的案例
- 学习 10 种良好的 XML 使用习惯
- Atlas学习手记(10):使用AlwaysVisibleControl Extender
- 坚持学习WF(10):在工作流中使用关联
- [学习笔记][C++Primer Plus]String类的使用