使用C ++中的new创建引用

时间:2013-11-10 07:03:54

标签: c++ reference

我有以下代码,似乎用new创建引用是可以的,但是当涉及用new创建一个对象时,当我尝试重新收集分配的内存时它会崩溃

float &f = *new float(1.3);
delete &f;
float f1 = *new float;
delete &f1;

我想知道区别,谢谢!

2 个答案:

答案 0 :(得分:1)

考虑:

float f1 = *new float;

它在免费商店中创建类型为float的对象,然后将原始对象复制到f1。您丢失了原始免费商店对象的地址,这会给您带来即时内存泄漏。

所有内存解除分配函数都要求传递给它们的地址应与内存分配函数返回的地址相同,因此当您调用{{1}时,最终会出现未定义的行为在未通过delete返回的地址上。

请注意,未定义的行为不会导致崩溃,但是没有崩溃并不意味着代码中没有问题。

答案 1 :(得分:0)

首先,“使​​用new创建引用”并不是您正在做的事情。要理解这一点,需要分解代码......

new float(1.3);

这为float分配4个字节的内存,使用1.3 double常量构造float,并返回指向内存开头的指针 - 4个字节中的第一个。

*new float(1.3);

这“取消引用”new运算符返回的指针,因此您不是读取指针值,而是读取它指向的4字节float数据。

float &f = *new float(1.3);

使用new提供的float构造引用f。虽然(AFAIK)引用实现为具有更大编译器优化潜力的指针(?),但这是人们抱怨的一部分。从概念上讲,引用浮点数,你不应该假设你可以检索地址,释放内存,从而使引用无效。

但是,正如您所发现的,它确实有效,您可以检索地址......

&f

生成指向引用位置的内存的指针,然后您可以

delete &f;

回答你的实际问题......

float f1 = *new float;

可以改写如下

float f1; //a float on the stack!
f1 = *new float; //should probably be: *new float(1.3)

不会初始化引用,而是复制由new分配给堆栈上的float的数据。复制后,new返回的内存地址将永远丢失 - 您已“泄露”内存。

现在就崩溃了。

&f1;

在堆栈上创建指向float f1的指针。此内存尚未由new或新最终使用的内存分配库创建。试图释放内存分配库中不存在的内存地址......

delete &f1;

...导致你的崩溃。

float &ffloat f1之间的差异:一个是引用,内部实现为指针(假设永远不会改变),一个是实际的浮点变量在堆栈上声明不引用其他内存。

你应该做的是

float *f = new float(1.3f);
// access f as *f = 1.2f or cout << *f
delete f;