C++ 在C+中创建一个新的引用+;

C++ 在C+中创建一个新的引用+;,c++,reference,C++,Reference,我有下面的代码,似乎用new创建一个引用是可以的,但是当用new创建一个对象时,当我试图回忆分配的内存时,它崩溃了 float &f = *new float(1.3); delete &f; float f1 = *new float; delete &f1; 我想知道区别,谢谢 考虑: float f1 = *new float; 它在自由存储上创建类型为float的对象,然后将原始对象复制到f1。您丢失了原始空闲存储对象的地址,这会导致即时内存泄漏 所有内存取消

我有下面的代码,似乎用new创建一个引用是可以的,但是当用new创建一个对象时,当我试图回忆分配的内存时,它崩溃了

float &f = *new float(1.3);
delete &f;
float f1 = *new float;
delete &f1;
我想知道区别,谢谢

考虑:

float f1 = *new float;
它在自由存储上创建类型为
float
的对象,然后将原始对象复制到
f1
。您丢失了原始空闲存储对象的地址,这会导致即时内存泄漏

所有内存取消分配函数都要求传递给它们的地址应与内存分配函数返回的地址相同,因此,当您对未通过
new
返回的地址调用
delete
时,会出现未定义的行为

请注意,未定义的行为并不强制要求崩溃,但没有崩溃并不意味着代码中没有问题。

首先,“使用new创建引用”并不完全是您要做的。要理解这一点,需要分解代码

new float(1.3);
这将为一个浮点分配4个字节的内存,使用1.3双常量构造浮点,并返回一个指向内存开头(4个字节中的第一个字节)的指针

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

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

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

&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分配的数据复制到堆栈上的浮点。复制后,
new
返回的内存地址将永远丢失-您的内存已“泄漏”

现在来看看它为什么会崩溃

&f1;
在堆栈上创建指向浮点
f1
的指针。此内存不是由
new
或new最终使用的内存分配库创建的。正在尝试释放内存分配库中不存在的内存地址

delete &f1;
…导致你坠机

float&f
float f1
之间的区别是:一个是引用,内部实现为指针(假定永远不会更改),另一个是堆栈上声明的实际浮点变量,不引用其他内存

你应该做的是

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

//以*f=1.2f的形式访问f或cout引用不是指针。感谢您的输入@H2CO3,但这里的混淆似乎是涉及多个操作<代码>新建
分配了一些内存并返回一个地址。例如,您可以有一行带有
newfloat的代码并且它会编译。下一部分,
*newfloat
取消对指针的引用,以获取该地址的值。赋值是另一个操作,与
new
运算符无关。引用是通过值(及其位置)初始化的,而不是
new
@jozxyqk,这是因为引用不是指针。@texasbruce
*
取消对指针的引用,而不考虑r/lvalue。例如,
*ptr=*otherPtr以复制值。这也编译了
*新浮点=*新浮点(1.3f)
。关于第一部分,看起来
&f
将生成与
new
返回的地址相同的地址。这有保证吗?(不是说应该这样做,只是对引用的实现方式感兴趣)@jozxyqk:这不一样。无论哪种情况,最终都会丢失原始对象的地址
&f
将返回不同的地址?我认为它返回相同的地址,只是不确定它是否有保证。
float*p=newfloat;浮动&f=*p;printf(“%p%p\n”,p和f)
给出了
0x1679010 0x1679010
@jozxyqk:它们不是等价的,你可以在这里发布的另一个答案中看到区别。我对delete&f崩溃原因的最初理解是,它使用delete非法检索堆栈外分配的内存,而delete应该只检索从堆中分配的内存。经过你令人信服的解释,我的想法是有道理的!谢谢