Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;新运算符是否保证返回的指针不会更改其值?_C++_Memory Management_Operating System_Standards - Fatal编程技术网

C++ C++;新运算符是否保证返回的指针不会更改其值?

C++ C++;新运算符是否保证返回的指针不会更改其值?,c++,memory-management,operating-system,standards,C++,Memory Management,Operating System,Standards,在C++中: 我的程序只有一个线程,在将内存分配给p之后,我的程序将只读取p所指的内存 标准对p的值有何规定 p是否会保留它在time=t0时获得的值,直到p的删除 或者,操作系统能否自行决定重新分配p所指的内存 它是否取决于N的值?p的值只是一个内存位置。它在分配后不会更改。它指向的内存可以更改。操作系统不会改变它。它可以由您的程序更改。如果只分配一个整数数组(例如),并为每个整数赋值。您可以放心,这些值不会更改,除非您显式地覆盖它们(或有这样做的错误)。堆分配的地址将保持不变,变量不会在没有

在C++中:

我的程序只有一个线程,在将内存分配给
p
之后,我的程序将只读取
p
所指的内存

标准对
p
的值有何规定

p
是否会保留它在time=t0时获得的值,直到
p
删除

或者,操作系统能否自行决定重新分配
p
所指的内存


它是否取决于
N
的值?

p的值只是一个内存位置。它在分配后不会更改。它指向的内存可以更改。操作系统不会改变它。它可以由您的程序更改。如果只分配一个整数数组(例如),并为每个整数赋值。您可以放心,这些值不会更改,除非您显式地覆盖它们(或有这样做的错误)。

堆分配的地址将保持不变,变量不会在没有您影响的情况下更改其值。您的
p
在删除后甚至会保留其值,但如果您尝试访问它,您将触发(希望)分段错误。
N
的值不起作用。

p的值在创建后不能移动。该标准使得这样做毫无意义:

3.7.4.1分配功能

…如果请求成功,则返回的值应为与任何 以前返回的值p1,除非该值p1随后被传递给delete运算符

(引用标准结束)



因此,如果在运行时,由于整合一些内存片段等原因,某个东西决定将p移动到另一个地址,则该标准已使原始p所指向的空间不可能被另一个内存分配使用。空间将被浪费

> P>内存模型和预期语义标准说明了一种可观察的行为,这些实现必须符合(参见第1.7段- C++内存模型)到1.10——多线程执行和数据竞赛(标准)(1)。这种可观察的行为应与标准中描述的抽象机器的行为相匹配。它将程序内存定义为一组字节序列,可以通过副作用操作(内存上的I/O)对其进行修改。指针本身就是存储在内存中的字节序列,因此遵循相同的规则。该模型还指定了未定义行为的情况,对于这些情况,可能会发生任何事情,包括内存损坏。此外,多线程程序可能会通过竞争条件(见1.10)在“背后”修改内存(我自己的措辞,不是实际引用)

new
运算符通过使用分配函数工作,分配函数返回内存地址,并且还必须遵守可观察行为规则

尽管如此,第1.9段(程序执行)在第8点中指出,在一致性实施的最低要求中:

对易失性对象的访问严格按照抽象机器的规则进行评估

换言之,尽管程序应呈现与标准中描述的模型相同的结果,但只有
volatile
才能保证严格遵守标准中描述的结果。非易失性存储可能不会以一致的方式被观察到(如果您已经在优化代码上使用了调试器,那么您可以清楚地看到内存内容更新中与程序源实际指定内容相关的奇怪模式)。 另一个重要点是
新的
运算符是可重载的,这意味着标准中描述的默认行为可能会被覆盖。如果标准的最低一致性实现(即,仅强制执行
volatile
变量观察)运行一个程序,其中
new
已被覆盖,并且不依赖
volatile
数据跟踪其内存堆,具有优化和强内联,返回指针的值在存储它们的变量中可能不会立即可见。如果优化过程确定变量的生存期可以从程序所描述的缩短,那么与该变量相对应的内存位置也有可能被重新调整用途,其内容也会发生变化,并在调试器中观察到,尽管程序没有指示这样的更新。然而,编译器的任务是确保程序的执行符合预期的行为:从程序的角度来看,变量将在其整个生命周期内保持其值,并且不会更改,除非程序以内存模型允许的任何方式通过更新指定它

在您的示例中,如果在程序中的
new
赋值之后多次访问变量
p
,则不会注意到该变量包含的值发生了变化,因为该赋值是标准要求的。如果您试图通过一些外部设备观察该变量的内存位置,那么您将跳出标准的抽象内存模型,并可能看到其内容的变化


(1) 使用版本N3485作为参考,段落编号在以后的版本中可能已更改

变量本身的值永远不会改变。不同的事情
p
可以保持它的值,并且
p
指向的内存可以重新分配。@juanchopanza所以操作系统可以自己决定(没有我编写的显式代码)重新分配内存吗?@uvts\U cvs它可以这样做,如果内存不足或以其他方式调用未定义的行为(UB)。但问题的关键(并非双关语)是指针只是一个包含数字的变量。这个数字不会自行改变(除非你
const size_t N = 1000;
int* p = new int[N];// time=t0