从java到C++——new和delete的动态内存管理

来源:互联网 发布:淘宝店铺首页大图图片 编辑:程序博客网 时间:2024/05/18 00:37

C++中定义了两个运算符来分配和释放内存:new分配内存,delete释放内存。

 

使用new来动态分配和初化对象


在自由空间分配的内存是无名的,因此new无法为其分配的对象命名,而是返回指向该对象的指针。

new 可以分配基本的数据类型变量,也可以为类分配对象的内存空间,然后返回指向该对象的指针。

如【例1】:

int *ip = new int;//动态分配一个int大小的空间,并返回int类型的指针赋给ip,该变量未被初化

cout << *ip << endl;

*ip = 0;//ip指向的变量进行初始化

cout << *ip << endl;

double *dp = new double;

cout << *dp << endl;

*dp = 1.2;

cout << *dp << endl;

 

string *sp = new string;//动态分配一个string对象的内存空间,并返回该对象的指针,默认初始化为空

cout << *sp << endl;//

*sp = "string test.";//string进行值值

cout << *sp << endl;

结果:

-842150451

0

-6.27744e+066

1.2

 

string test.

 

New的用法总结:

1.动态分配的对象是默认初始化的

对于基本数据类型的变量的值是不定义的,如上面的ipdp指向的变量是未定义的,是一个任意值;而对于stringstring是一个类,用了string的默认构造函数对基进行初始化。


2.可以用直接初始化方式初始化一个动态分配的对象

【例2】:

int *i_p1 = new int();

int *i_p2 = new int(10);

cout << *i_p1 << endl;

cout << *i_p2 << endl;

delete i_p1;

delete i_p2;

string *s_p1 = new string();

string *s_p2 = new string("hello world");

cout << *s_p1 << endl;

cout << *s_p2 << endl;

delete s_p1;

delete s_p2;

结果为:

0

10

 

hello world

 




delete释放动态内存

new分配的内存并不会自己释放,要用delete进行释放后将内存归还给系统。动态内存使用完必后必须用delete释放内存,否则会出现内存泄露。

delete表达式:delete p;//p必对应指针,可以为空指针

Delete完成两个动作:销毁给定指针指向的对象,释放对应内存。

对应【例1】,要对其进行释放内存,如下:

【例3】:

int *ip = new int;//动态分配一个int大小的空间,并返回int类型的指针赋给ip,该变量未被初化

cout << *ip << endl;

*ip = 0;//ip指向的变量进行初始化

cout << *ip << endl;

delete ip;//使用完后释放内存

double *dp = new double;

cout << *dp << endl;

*dp = 1.2;

cout << *dp << endl;

delete dp;//使用完后释放内存

 

string *sp = new string;//动态分配一个string对象的内存空间,并返回该对象的指针,默认初始化为空

cout << *sp << endl;//

*sp = "string test.";//string进行值值

cout << *sp << endl;

delete sp;//使用完后释放内存

 

1.传递给delete的指针必须指向动态分配的内存,或是一个空指针;

【例4】:

int i = 1;

int *p = &i;

delete p;//不能释放非动态分配的内存空间


2.动态分配的内存只能释放一次;

【例5】:

int *ip = new int;

*ip = 0;

cout << *ip << endl;

delete ip;//使用完后释放内存

delete ip;//不能重复释放内存

3.动态对象的生存期直到被释放时为止;

如【例6】:

void function()

{

string *s = new string("new string!");//分配一个动态对象,生存期开始

cout << *s << endl;

}

 

void use_function()

{

function();//调用了function();但未释文s指向的内存,该内存一直存在

}

针对这种情况,使用完动态分配的内存后必须在function()中释放,域返回一个指针,由调用它的函数释放!

方法一:

void function()

{

string *s = new string("new string!");//分配一个动态对象,生存期开始

cout << *s << endl;

delete s;//用完后释放

}

方法二:

string* function()

{

string *s = new string("new string!");//分配一个动态对象,生存期开始

cout << *s << endl;

return s;

}

 

void use_function()

{

string *sp = function();

delete sp;//用完后释放

}

 

4.养成delete之后重置指针为空的习惯

【例7】:

void function()

{

string *s = new string("new string!");

cout << *s << endl;

delete s;

cout << *s << endl;//程序会出现运行时异常,因为s指向的内存已经被释放,所以delete s后要将s置空s = NULL;

}






动态分配数组


相信,数组大家都不陌生,很轻松就可以定义一个指定大小的数组。 很多程序中都会遇到这样一个场景,要使用一个数组,但在程序编写时并不确定其大小,需在程序运行时才知道。这就需要使用动态数组,在运行时动态分配指定大小的数组。


new分配一个动态数组

语法格式:

T *p = new T[n];   

T可以为基本数据类型,也可以为类,new T[n]返回一个指向第一个T类型元素的指针。

【例8

void newIntTest(int n)

{

int *arr = new int[n];//分配一个大小为nint型数组

for (size_t i = 0; i < n; i++)

{

cout << arr[i] << "   ";//数组未被初始化值

}

cout << endl;

 

string *arrStr = new string[n];//分配一个大小为nstring型数组

for (size_t i = 0; i < n; i++)

{

cout << arrStr[i] << "   ";//动态分配的对象是默认初始化,所以数组的每个元素都为空""

}

cout << endl;

}

 

可以用数组的类型别名来动态分配数组

typedef int arrInt[5];//arrInt表示42int的数组类型

int *arr = new arrInt;

 

初始化动态分配的数组

与分配单个变量和对象一样,动态分配的数组也是默认初始化的。默认的初始化往往不是我们需要的值,我们可以在分配数组时就给定初始化的值。

【例9】:

void newIntTest(int n)

{

int *arr = new int[n]();//分配一个大小为nint型数组

for (size_t i = 0; i < n; i++)

{

cout << arr[i] << "   ";//数组未被初始化值

}

cout << endl;

 

string *arrStr = new string[n]();//分配一个大小为nstring型数组

for (size_t i = 0; i < n; i++)

{

cout << arrStr[i] << "   ";//动态分配的对象是默认初始化,所以数组的每个元素都为空""

}

cout << endl;

}

 

动态分配一个空数组是合法的,如int *arrInt = new int[0]; 对于0长度的数组来说,返回的指针类似于一个迭代器中的尾后指针,不可对该指针进行解引用,可以对指针进行加减操作。


释放数组

对于动态分配的数组,同样要在使用完后释放内存。释放数组要用一种特殊形式的delete,格式如下:

delete []arr;

arr为指向数组首元素的指针。

4 0
原创粉丝点击