C++ : 再谈new的使用

1. 使用new运算符初始化

1.1 如果要为内置类型分配存储空间并初始化,可在类型名后面加上初始值,并将其用括号扩起。

int* a = new int(5);
double* b = new double(5.6);

这种做法也适合类的构造函数。

1.2 初始化常规结构或数组,需要用大括号的列表初始化(C++11)

struct Base
{
	int a; int b;
}
Base* one = new Base {1,2};

int* nums = new int[3] {1, 2, 3};

还可将初始化列表用于单值变量:

int* num =  new int {};
double* db = new double {1.2};

2.new失败时

new可能找不到请求的内存量。起初,这种情况让new返回空指针,但现在将引发异常 std::bad_alloc。

3.new:运算符、函数和替换函数

运算符new和new[]分别调用下列函数:

void* operator new(std::size_t); // new
void* operator new[](std::size_t); // new[]

这些函数被称为分配函数, 位于全局名称空间中。
是由delete和 delete[]调用的释放函数

void operator delete(void*);
void operator delete[](void*);

替换:

int* p1 = new int;
//->
int* p1 = new(sizeof(int));

int* p2 = new int[10];
//->
int* p2 = new(sizeof(int) * 10);

delete p1;
//->
delete(p1);

C++将这种函数称为可替换的。这意味着如果你有足够的知识和意愿,可为new和delete提供替换函数,并根据需要对其进行定制。

4.定位new运算符

头文件:

#include<new>

new运算符还有一种变体,被称为 定位(placement)new运算符, 可以使你能够指定要使用的内存位置
使用时需要加头文件,并将new运算符用于提供了所需地址的参数。

示例:

#include<new>
using namespace std;

char buffer1[20];
char buffer2[200];
int main(void)
{
	//普通new,在堆区申请
	int* p1 = new int;
	int* p2 = new int[10];
	//定位new在指定位置申请
	int* p3 = new(buffer1) int;
	int* p4 = new(buffer2) int[10];

	delete p1;
	delete[]p2;
	delete p3;
	delete[]p4;
	return 0;
}

在这里插入图片描述

通过监视器可以看出 定位new申请空间的地址,和指定的位置相同。

程序示例

#include<iostream>
#include<new>
using namespace std;

const int BUF = 512;
const int N = 5;
char buffer[BUF];
const int MOD = 1000;

int main(void)
{
	double* pd1, * pd2;
	int i;
	cout << "Calling new and placement new:\n";
	pd1 = new double[N];
	pd2 = new(buffer) double[N];

	for (i = 0; i < N; ++i)
	{
		pd2[i] = pd1[i] = MOD + 20.0 * i;
	}
	cout << "Memory addresses:\n" << "heap: " << pd1
		<< " static: " << (void*)buffer << endl;
	cout << "Memory contents:\n";
	for (i = 0; i < N; ++i)
	{
		cout << pd1[i] << " at " << &pd1[i] << "; ";
		cout << pd2[i] << " at " << &pd2[i] << endl;
	}

	cout << "\nCalling new and placement new a second time:\n";
	double* pd3, * pd4;
	pd3 = new double[N];
	pd4 = new(buffer) double[N];
	for (i = 0; i < N; ++i)
	{
		pd4[i] = pd3[i] = MOD + 40.0 * i;
	}
	cout << "Memory contents:\n";
	for (i = 0; i < N; ++i)
	{
		cout << pd3[i] << " at " << &pd3[i] << "; ";
		cout << pd4[i] << " at " << &pd4[i] << endl;
	}

	cout << "\nCalling new and placement new a third times:\n";
	delete[]pd1;
	pd1 = new double[N];
	pd2 = new(buffer + N * sizeof(double)) double[N];
	for (i = 0; i < N; ++i)
	{
		pd2[i] = pd1[i] = MOD + 60.0 * i;
	}
	cout << "Memory contents:\n";
	for (i = 0; i < N; ++i)
	{
		cout << pd1[i] << " at " << &pd1[i] << "; ";
		cout << pd2[i] << " at " << &pd2[i] << endl;
	}
	delete[]pd1;
	delete[]pd3;

	return 0;
}

运行示例:

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_索伦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值