动态内存

程序拥有:1.静态内存;2.栈内存;3.自由空间 / 堆(储存动态分配的对象)

一. new 与 delete 运算符
1.new 运算符

1).动态分配内存
new 表达式在自由空间构造一个 int 型(无名)对象,并返回该对象的指针:

int *pi = new int;

2).初始化对象
a.未显式初始化:默认初始化:内置类型或组合类型的值是未定义的,类类型用默认构造函数初始化;

int *pi = new int; //pi指向一个未定义的int
string *ps = new string; // ps指向一个空 string(默认构造函数)

内置类型:算术类型(bool, char, int, float, double)和空类型(空类型不对应具体的值,仅用于一些特殊的场合,如当函数不返回任何值时使用空类型(void)作为返回类型);
组合类型:引用、指针、数组;

b.显式初始化:直接初始化(与拷贝初始化区分):可以使用:
(1).传统构造方式(圆括号)
(2).列表初始化(花括号)或者值初始化

int *pi = new int(1024);

vector<int> *pv = new vector<int>{0, 1, 2};
int *pi1 = new int(); // 值初始化为0,*pi1的值为0

(3).使用 auto 和初始化器

auto p1 = new auto(obj); // obj 是一个某类型的对象,p1指向从 obj 推断出的类型;

3).动态分配 const 对象

const int *pci = new const int(1024);
const string *pcs = new const string; //默认初始化

a. const 对象必须初始化,对于一个定义了默认构造函数的类类型,可以隐式初始化;
b.返回一个指向 const 的指针;

4).内存耗尽

int *p1 = new int; //默认情况下,分配内存失败会抛出一个类型为 bad_alloc 的异常
int *p2 = new (nothrow) int; //定位new:向 new 传递名为 nothrow 的对象,这种情况下分配内存失败会返回一个空指针;

2.delete 运算符

1).释放动态内存
delete 表达式执行两个动作:销毁对象+释放内存;
传递给 delete 的指针必须是:(1).用 new 分配内存的指针;(2).空指针;

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

void factory(T arg) {
	Foo *p = new Foo(arg);
} // p 离开它的作用域,局部变量 p 被销毁,但它所指向的对象什么也不会发生,即此动态内存也不会被释放

3). delete 之后重置指针值
delete 之后,指针(在某些机器上)就变成了空悬指针:指向一块曾经保存数据对象但现在已经无效的内存;
避免空悬指针:在指针离开作用域前释放掉它所关联的内存,若需要保留指针,可以在 delete 之后将 nullptr 赋予指针;

3.动态数组
1).使用 new 和 delete

1.
int *pia = new int[size]; // pia 指向数组首位
2.
typedef int arrT[42];
int *p = new arrT; //使用表示数组类型的类型别名,与以下语句等价:
int *p = new int[42];

分配的内存不是数组类型,不能调用 begin 或 end 函数;

a.初始化数组:
(1).默认初始化
(2).值初始化
(3).元素初始化器的花括号列表
不能用 auto 分配数组;

int *pia = new int[10]; //值未定义
int *pia2 = new int[10](); //值均为0
int *pia3 = new int[10]{0, 1, 2, 3}; //之后的六个值初始化
string *psa = new string[10]; //空 string
string *psa2 = new string[10](); //空 string
string *psa3 = new string[10]{"a", "an"};

b.分配一个空数组是合法的

char arr[0]; //错误
char *cp = new char[0]; //正确,但 cp 不能解引用

c.释放动态数组

delete [] pa; //pa 必须指向一个动态分配的数组或为空指针

元素按逆序销毁,[] 提示编译器此指针指向一个对象数组的第一个元素;

2).智能指针

3). allocator 类

4.题目
1).

class Point {
public:
	Point();
	Point(int x, int y);
	~Point();
	int getX() const; 
	int getY() const; 
	void move(int newX, int newY);
private:
	int x, y;
};

构造函数和 move 成员函数有什么区别:
getX 和 getY 为什么用 const:
~Point 函数是什么意思:

2).

class ArrayOfPoints { //动态数组类
	public:
		ArrayOfPoints(int size) : size(size) {
			points = new Point[size];
		}
		~ArrayOfPoints() {
			cout << "Deleting..." << endl;
			delete [] points;
		}
		Point& element(int index) {
			return points[index];
		}
	private:
		Point *points; //指向动态数组首地址
		int size; //数组大小
};

~ArrayOfPoints 函数是什么意思:
element 函数为什么用引用:要修改原数组中元素而不是想得到一个副本;

二.智能指针

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值