如果你解引用' new int '会发生什么?
What happens if you dereference `new int`?
以下内容安全吗?
*(new int);
我得到的输出是0
.
这是未定义的,因为你正在读取一个具有不确定值的对象。表达式new int()
使用零初始化,保证零值,而new int
(没有括号)使用默认初始化,给您一个不确定的值。这实际上相当于说:
int x; // not initialised
cout << x << 'n'; // undefined value
但是,由于您立即解引用了指向您刚刚分配的对象的指针,并且没有将指针存储在任何地方,这就构成了内存泄漏。
注意,这种表达式的存在并不一定使程序病态;这是一个完全有效的程序,因为它在读取对象之前设置了对象的值:
int& x = *(new int); // x is an alias for a nameless new int of undefined value
x = 42;
cout << x << 'n';
delete &x;
这是未定义的行为(UB),因为你正在访问一个不确定的值,c++ 14清楚地使这种未定义的行为。我们可以看到,没有初始化的new
是默认初始化的,从c++ 14标准草案5.3.4
New段落17说(强调我的未来):
如果省略new-initializer,则默认初始化对象(8.5)。[注:如果没有初始化,对象有一个。不确定的值。-end note]
for int这意味着一个不确定的值,来自8.5
节7,其中说:
默认初始化T类型的对象意味着:
-如果T是(可能是cv限定的)类类型(第9条),则调用T的默认构造函数(12.1)(and)如果T没有默认构造函数,或者重载解析(13.3)导致错误,则初始化是错误的歧义(或在初始化上下文中被删除或不可访问的函数中);
—如果T是数组类型,则每个元素默认初始化;
- ,否则不进行初始化。
我们可以从8.5
节看到,产生一个不确定的值是未定义的:
如果没有为对象指定初始化式,则该对象为 default-initialized 。当存储对象具有自动或获取动态存储时长时,对象具有不确定值value,如果没有对对象进行初始化,则对象保留一个不确定的值,直到该值被替换(5.17)。[注:具有静态或线程存储时间的对象是零初始化,参见3.6.2。-结束提示如果计算产生了一个不确定的值,则该行为是未定义的,除了以下情况
和所有异常都与unsigned窄字符有关,而int则不是。
Jon举了一个有趣的例子:
int& x = *(new int);
可能不是很明显为什么这不是未定义的行为。需要注意的关键点是,生成值是未定义的行为,但在这种情况下没有生成任何值。我们可以通过8.5.3
References小节看到这一点,该小节涵盖了引用的初始化,它说:
对类型"cv1 T1"的引用由类型"cv2 T2"的表达式初始化,如下所示:
—如果引用是左值引用,且初始化表达式
-是左值(但不是位域)," cv1 T1 "与" cv2 T2 "或
是引用兼容的
,接着说:
则将引用绑定到中的初始化表达式lvalue第一个案例……[注:通常的左值到右值(4.1),数组到指针(4.2)和函数到指针(4.3)标准在这种情况下,不需要转换,因此被抑制完成对左值的直接绑定。-end note]
有可能计算机有int
的"陷阱"值:无效值,例如校验和位在与预期状态不匹配时引发硬件异常。
通常,未初始化的值会导致未定义的行为。先初始化
否则,不,解引用new-expression并没有什么错误或真正不寻常的。下面是一些奇怪的,但完全有效的代码使用您的结构:
int & ir = * ( new int ) = 0;
…
delete & ir;
首先,Shafik Yaghmour在他的回答中提到了《标准》。这是最好的、完整的、权威的答案。尽管如此,让我试着给你们一些具体的例子来说明上述几点。
这段代码是安全的,格式良好且有意义的:
int *p = new int; // ie this is a local variable (ptr) that points
// to a heap-allocated block
但是,不能对指针解引用,因为这会导致未定义的行为。IE可能会得到0x00或0xFFFFFFFF,或者指令指针(也就是Intel上的RIP寄存器)可能跳转到一个随机位置。电脑可能会死机。int *p = new int;
std::cout << *p; // Very, bad. Undefined behavior.
运行时检查器,如Valgrind和ASan将捕捉到这个问题,标记它,并以一个漂亮的错误消息崩溃。
但是,初始化您分配的内存块是完全可以的:
int *p = new int;
*p = 0;
背景信息:这种编写规范的特殊方式对性能非常有用,因为实现替代方法的成本非常高。
注意,根据标准参考,有时初始化是便宜的,所以你可以这样做:
// at the file scope
int global1; // zero-initialized
int global2 = 1; // explicitly initialized
void f()
{
std::cout << global1;
}
这些东西进入可执行文件的部分()。
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- "类模板示例<int>;"语句对 C++11 是什么意思?
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 是什么导致了这种使用三进制而不是短整型的有符号int到无符号int转换
- 关于int :0有什么特别之处在C++
- C++ 未初始化的本地(非全局)int 数组中的元素类型到底是什么?
- ((int) a) 和 (int(a)) 之间的区别是什么?
- 在 C 和 C++ 中作为函数参数,int **a 和 int a[][] 之间有什么确切的区别
- map<string, int> m= {}; 在C++中是什么意思?
- 有什么方法可以使用 int 变量来完成组件名称吗?
- int x_ 和 int x 在C++中有什么区别
- 行 - " vector<int> used(adj.size(), 0); "是什么意思?
- int** a = new int*[n]();这个函数有什么作用?
- *(int*)&data[18]在这段代码中实际上做了什么?
- 无符号长整型和无符号 int 之间有什么区别,这 2 种类型应该如何在 c# 中封送?
- 在 c++ 上,您通常使用什么 int 值、'255' 和十六进制值'0xff'?
- 有人可以向我解释什么[](int i){返回i%2 == 0;} 方法
- 更大的在集合中扮演什么<int>角色?
- 如何在矩阵中使用指针.这行代码的作用是什么:int r=**(++b);
- 编译器在这里做什么:int a = b * (c * d * + e)