内存管理:new和delete
来源:互联网 发布:服装连锁收款软件 编辑:程序博客网 时间:2024/05/01 18:13
C++ 指针(二)--c++
一、内存管理:new和delete
1、new操作符:从操作系统获得内存块,并返回该内存块的首地址。
delete操作符:将new申请的内存返还给操作系统。
开始一个简单的例子:
#include <iostream>
#include<cstring>
using
namespace
std;
int
main()
{
char
* str=
"it is a good job!"
;
int
len=
strlen
(str);
char
* ptr=
new
char
[len+1];
strcpy
(ptr,str);
//ptr=str; //错误,这样是ptr和str都指向字符串。这里ptr和str应该指向不同的地址。
cout<<
"ptr="
<<ptr<<endl;
delete
[] ptr;
return
0;
}
指针
=
关键字
变量的数据类型
char类型变量的数目(方括号)
2.使用new的类
#include<iostream>
using
namespace
std;
class
String
{
public
:
String(
char
* s)
{
int
len=
strlen
(s);
str=
new
char
[len+1];
strcpy
(str,s);
}
~String()
{
cout<<
"where?"
<<endl;
delete
[] str;
}
void
display()
{
cout<<str<<endl;
}
private
:
char
* str;
};
int
main()
{
String str=
"hello! word!"
;
str.display();
return
0;
}
1)在构造函数中使用new获得内存空间。
2)既然使用new来分配内存空间,因而析构函数也变得很重要。(因为在创建对象的时分配了内存空间,则当这些对象不再需要时就很有必要释放这些空间)。析构函数在对象销毁时自动调用的例程,所以放入delete恰好。
问题:如果一个类的两个对象执行了s1=s2这样的操作(即出现两个对象的指针指向同一个内存地址),而此时一个对象被删除(如含有其中一个对象的调用函数结束后返回时),这样申请的内存地址被收回,这样就导致另一个对象的是一个无效的指针了。
这个错误一定要重视,因为很容易疏忽。怎样才能写一个更聪明的析构函数呢?? 后面揭晓…
二、对象与指针
1、对象指针
有时在程序的编写时并不知道需要创建多少个对象。当出现这中情况时,就可以在程序运行中使用new来穿件对象。这里,new返回的是一个指向未命名对象的指针。
例子:
#include<iostream>
using
namespace
std;
class
Distance
{
public
:
void
getdist();
void
showdist();
private
:
int
feet;
float
inches;
};
void
Distance::getdist()
{
cout<<
"Enter the feet:"
; cin>>feet;
cout<<
"Enter the inches:"
;cin>>inches;
}
void
Distance::showdist()
{
cout<<
"The feet:"
<<feet<<endl;
cout<<
"The inches:"
<<inches<<endl;
}
int
main()
{
Distance dd;
dd.getdist();
dd.showdist();
Distance* ptr=
new
Distance;
// pointer to Distance,points to new Distance object
ptr->getdist();
//这里如果是点运算符就会出错
ptr->showdist();
//因为点运算符要求它的左运算符是一个变量,而ptr为一个指针。
return
0;
}
上面标注的地方除了用成员访问运算符(->)表示之外,我们还可以这样(*ptr).getdist(); //ok,but inelegant (圆括号是必须的,因为点运算符的优先级比间接引用运算符要高).
2、对象指针数组
Distance* distptr[100];
distptr[j]=
new
Distance;
//*(distptr+j)=new Distance;
distptr->getdist();
distptr->showdist();
注意:数组表示法distptr[j]等价于指正表示法*(distptr+j),由于是指针数组,上面两种表示的方法的元素还是指针(指向对象的指针)
distptr->getdist(); 表示执行了由数组distptr的第j个元素 所指向的Distance对象的成员函数。
三、链表
链表提供了一种不使用数组但更为灵活的存储系统,每个数据项都是按照需要通过new来获取的,且数据之间是通过指针链接起来的。
单个数据项之间并不需要和数组元素一样在内存中相邻分配,相反他们可以分散到任何地方。
例子:
#include <iostream>
using
namespace
std;
struct
link
{
int
data;
//表示对象的单个数据项
link* next;
//指向下一个链接项
};
class
linklist
{
public
:
linklist():first(NULL) {}
void
addlist(
int
d);
//增加链接项
void
display();
//显示链接内容
private
:
link* first;
};
void
linklist::addlist(
int
d)
//增加链接项
{
link* newptr=
new
link;
//创建一个新的link结构类型
newptr->data=d;
//将参数的值传递给结构变量data
newptr->next=first;
//指针next指向first指向的任何地址(在这里是链表头)
first=newptr;
//将指针first指向这个新的链接项
}
void
linklist::display()
{
link* nowptr=first;
while
(nowptr!=NULL)
{
cout<<nowptr->data<<endl;
nowptr=nowptr->next;
//指针移动到下一个链表的地址
}
}
int
main()
{
linklist ll;
ll.addlist(22);
ll.addlist(33);
ll.addlist(44);
ll.display();
return
0;
}
注意:在使用link结构的时候含有一个指向同类型结构的指针。同样的在类中也可以这么使用:
class
sampleclass
{
sampleclass* ptr;
//this is fine!
sampleclass obj;
//can't do this!!
};
但是这里要特别注意:虽然类中可以包含一个指向同类型对象的一个指针,但不能包含一个同类的对象。
四、指向指针的指针
看个例子:
#include<iostream>
#include <string>
using
namespace
std;
class
person
{
public
:
void
SetName()
{
cout<<
"Enter name:"
; cin>>name;
}
void
PrintfName()
{
cout<<name;
}
string GetName()
{
return
name;
}
private
:
string name;
};
int
main()
{
void
bsort(person**,
int
);
//排序
person* perptr[100];
int
n=0;
char
ch;
do
{
*(perptr+n)=
new
person;
(*(perptr+n))->SetName();
n++;
cout<<
"Enter another?"
;
cin>>ch;
}
while
(ch==
'y'
);
cout<<
"姓名排序前:"
;
for
(
int
j=0;j<n;j++)
{
perptr[j]->PrintfName();
cout<<
" "
;
}
bsort(perptr,n);
cout<<
"\n姓名排序后:"
;
for
(
int
j=0;j<n;j++)
{
perptr[j]->PrintfName();
cout<<
" "
;
}
cout<<endl;
return
0;
}
void
bsort(person** ptr,
int
n)
//排序
{
void
order(person**,person**);
int
j,k;
for
(j=0;j<n-1;j++)
for
(k=j+1;k<n;k++)
order(ptr+j,ptr+k);
}
void
order(person** ptr1,person** ptr2)
//比较
{
if
((*ptr1)->GetName()>(*ptr2)->GetName()))
{
person* tem;
tem=*ptr1;
*ptr1=*ptr2;
*ptr2=tem;
}
}
1)注意到数据类型person**,表示这些参数被用来传递perptr指针数组的地址。本身perptr数组中存的就是指针,因此指针数组的地址是一个指向指针的指针。
2)因为数组perptr包含的是指针,因而:perptr[j]->PrintfName(); 表示执行perptr数组的j号元素所指向的对象的PrintfName()成员函数。
3)(*ptr1)->GetName();
其中ptr1是一个指向指针的指针,因此(*ptr1)表示指针数组的元素。总体意思就是执行perptr数组的元素(*ptr1)所指向的对象的PrintfName()成员函数。
- 内存管理:new和delete
- new和delete管理内存
- 实例详解new和delete 内存管理
- C++内存管理之new和delete
- 动态管理内存之new和delete
- 内存管理 new、delete’
- 动态内存管理---new&delete
- 动态内存管理new&delete
- 动态内存管理(new/delete)
- 定制new和delete更改内存管理方案
- new和delete在高级内存管理中的应用
- C++动态内存管理之深入探究new和delete
- c++ 重载new和delete实现内存管理
- 【C++】动态内存管理(new,delete,new[],delete[])
- new和delete分配内存
- C++内存管理基础之new & delete
- C++内存管理基础之new & delete
- C++内存管理基础之new & delete
- 一个老程序员的建议
- Distributed_QoS_Evaluation_for_Real-World_Web_Services
- 【ORACLE】oracle数据文件损坏,出现错误:ora-01033:oracle initialization or shutdown in progress
- C++new的用法
- 【图染色】POJ 1419 & UVA 193
- 内存管理:new和delete
- 摩托罗拉 Moto XT800的CPU多少?
- POJ 1664 求m个苹果放入n个盘子的不同放法数目 递归 分类讨论
- MFC的消息映射有什么作用
- VirtualBox虚拟机实现桥接方式
- C标准库参考指南系列译文(12)stdio.h(A)
- Android Camera拍照常见问题小结
- 比较决策树和回归
- eclipse导出javadoc时编码错误或不显示注释的解决办法