热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C或C++是否保证array<array+SIZE?

假设你有一个数组:intarray[SIZE];或者int*array=new(int[

假设你有一个数组:

int array[SIZE];

或者

int *array = new(int[SIZE]);

C 或 C++ 是否保证array ,如果是,在哪里?

我知道无论语言规范如何,许多操作系统通过为内核保留虚拟地址空间的顶部来保证此属性。我的问题是语言是否也保证这一点,而不仅仅是绝大多数实现。

举个例子,假设一个操作系统内核处于低内存中,有时会向用户进程提供虚拟内存的最高页面,以响应mmap对匿名内存的请求。如果malloc::operator new[]直接要求mmap分配一个巨大的数组,并且数组的末尾紧靠虚拟地址空间的顶部,从而array + SIZE环绕为零,这是否等于该语言的不合规实现?

澄清

请注意,问题不是问 about array+(SIZE-1),它是数组最后一个元素的地址。那一个保证大于array。问题是关于超过数组末尾的指针,或者p+1何时p是指向非数组对象的指针(所选答案指向的标准部分明确表示以相同方式处理)。

计算器要我解释,为什么这个问题是不一样的这一个。另一个问题询问如何实现指针的总排序。另一个问题本质上归结为一个库如何实现std::less它甚至可以用于指向不同分配对象的指针,标准说只能比较相等,而不是大于和小于。

相比之下,我的问题是关于数组末尾的一个是否总是保证大于数组。我的问题的答案是或否实际上并没有改变你将如何实施std::less,所以另一个问题似乎并不相关。如果与数组末尾的比较是非法的,那么std::less在这种情况下可能只是表现出未定义的行为。(此外,通常标准库是由与编译器相同的人实现的,因此可以自由利用特定编译器的属性。)

回答


是的。来自第6.5.8节第 5 段。

如果表达式 P 指向数组对象的一个​​元素,而表达式 Q 指向同一个数组对象的最后一个元素,则指针表达式 Q+1 比较大于 P。

表达式array是 P。表达式array + SIZE - 1指向 的最后一个元素array,也就是 Q。因此:

array + SIZE = array + SIZE - 1 + 1 = Q + 1 > P = array



  • @Wyck - it doesn&#039;t prohibit such an implementation, _as long as it ensures that `<` is consistent with it_.


  • @Wyck, you might not be able to put anything at the top position of the address space, if I&#039;m reading cppreference.com correctly: ["a pointer to an object that is not an element of an array is treated as if it were pointing to an element of an array with one element"](https://en.cppreference.com/w/c/language/operator_comparison)


  • @ilkkachu: Objects whose address is not taken could be placed at the top of address space or at whatever physical address would match a null pointer&#039;s representation. Since most non-trivial programs will have at least two objects whose address is not taken, a requirement that any objects whose address is taken have to go elsewhere doesn&#039;t reduce the amount of practically useful storage.


  • Does this imply that you cannot create an implementation that puts an array at the top of the address space? Because (array= ((int*)0xFFFFFFFC))+ 1 might be 0x00000000? (32-bit address space, 4-byte int example)


  • @Wyck : You seem to be conflating the runtime values of the variables `array`, `SIZE`, `P`, and `Q` with actual virtual memory addresses. Sure, having pointers contain bit patterns identical to virtual memory addresses is an easy implementation, but it is not mandatory. As a concrete example, a pointer to a (16-bit) word at an odd address on an MC68000 cannot be directly dereferenced since [non-byte dereferencing an odd address on that architecture throws exceptions](http://mrjester.hapisan.com/04_MC68/Sect01Part06/Index.html).


  • @EricTowers how is that a counterexample? A conforming C implementation just wouldn&#039;t allow objects to be created on odd addresses. We call that *alignment*.


  • @EricTowers: A conforming implementation is required to ensure that it allocates objects with an alignment that will be compatible with whatever means it uses to accesses them. If e.g. a hardware platform has a 32-bit load instruction that works with arbitrarily-aligned addresses, and a load-multiple instruction that only works with 32-bit-aligned addresses, an implementation could at its leisure either ensure that 32-bit objects are aligned and use both kinds of instructions to access them, or use only the former kind of instruction but then place objects with arbitrary alignment.




回答


C 需要这个。第6.5.8节第 5 段说:

指向具有较大下标值的数组元素的指针比较大于指向具有较小下标值的同一数组元素的指针

我确信 C++ 规范中有类似的东西。

这一要求有效地防止了在公共硬件上分配环绕地址空间的对象,因为实现有效实现关系运算符所需的所有簿记是不切实际的。



  • @Neil You&#039;re allowed to form a pointer just past the end, but not allowed to dereference it.


  • Note, that `array + SIZE` does not point to any element of `array`. It points to element just after the last one.


  • The “bookkeeping necessary to implement the relational operator efficiently” is trivial: p q are equivalent to p−q <0, p−q = 0, and p−q > 0, where p−q is computed in the width of the address space bits. As long as every supported object is less than half the size of the address space, p−q must fall in the right region.




回答


int *array = new(int[SIZE]);SIZE为零时,保证不成立。

的结果new int[0]必须是一个可以0添加到它的有效指针,但array == array + SIZE在这种情况下,严格小于测试将产生false



  • You got me, I should have specified I was assuming `SIZE > 0`...




回答


这是在 C++ 中定义的,来自 7.6.6.4(当前C++23 草案的p139 ):

当一个整数类型的表达式 J 与指针类型的表达式 P 相加或减去时,结果的类型为 P。

(4.1) — 如果 P 的计算结果为空指针值而 J 的计算结果为 0,则结​​果为空指针值。

(4.2) — 否则,如果 P 指向具有 n 个元素的数组对象 x 的数组元素 i (9.3.4.5),则表达式 P + J 和 J + P(其中 J 的值为 j)指向(可能-假设)数组元素 i + j of x 如果 0 <= i + j <= n 并且表达式 P - J 指向(可能是假设的)数组元素 i ?如果 0 <= i ? j <= n。

(4.3) — 否则,行为未定义。

请注意,4.2 明确具有“<= n”,而不是“

数组元素的排序在 7.6.9 (p141) 中定义:

(4.1) 如果两个指针指向同一个数组的不同元素,或者指向其子对象,则要求指向下标较高的元素的指针比较大。

这意味着对于 n > 0 的所有明确定义的情况,假设元素 n 将比数组本身(元素 0)更大。





回答


C++ 中的相关规则是[expr.rel]/4.1:

如果两个指针指向同一个数组的不同元素,或者指向其子对象,则需要指向下标较高的元素的指针比较大。

上面的规则似乎只涵盖了指向数组元素的指针,并array + SIZE没有指向数组元素。然而,正如脚注中提到的,一个最后一个指针在这里被视为一个数组元素。相关的语言规则在[basic.compound]/3 中:

为指针运算的目的([expr.add])和比较([expr.rel],[expr.eq]),过去的阵列的最后一个元件的端部的指针xÑ元件被认为是等同于指向假设数组元素n的指针x和类型T不是数组元素的对象被认为属于具有一个类型元素的数组T

所以 C++ 保证array + SIZE > array(至少当SIZE > 0),以及&x + 1 > &x任何对象x






推荐阅读
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • Codeforces Round #566 (Div. 2) A~F个人题解
    Dashboard-CodeforcesRound#566(Div.2)-CodeforcesA.FillingShapes题意:给你一个的表格,你 ... [详细]
  • 使用GDI的一些AIP函数我们可以轻易的绘制出简 ... [详细]
  • 优化局域网SSH连接延迟问题的解决方案
    本文介绍了解决局域网内SSH连接到服务器时出现长时间等待问题的方法。通过调整配置和优化网络设置,可以显著缩短SSH连接的时间。 ... [详细]
  • 本文介绍了一种解决二元可满足性(2-SAT)问题的方法。通过具体实例,详细解释了如何构建模型、应用算法,并提供了编程实现的细节和优化建议。 ... [详细]
  • HBase运维工具全解析
    本文深入探讨了HBase常用的运维工具,详细介绍了每种工具的功能、使用场景及操作示例。对于HBase的开发人员和运维工程师来说,这些工具是日常管理和故障排查的重要手段。 ... [详细]
  • 深入剖析 DEX 赛道:从 60 大头部项目看五大趋势
    本文通过分析 60 大头部去中心化交易平台(DEX),揭示了当前 DEX 赛道的五大发展趋势,包括市场集中度、跨链协议、AMM+NFT 结合、新公链崛起以及稳定币和衍生品交易的增长潜力。 ... [详细]
  • 本文详细介绍了C语言中的指针,包括其基本概念、应用场景以及使用时的优缺点。同时,通过实例解析了指针在内存管理、数组操作、函数调用等方面的具体应用,并探讨了指针的安全性问题。 ... [详细]
  • 本题探讨了在一个有向图中,如何根据特定规则将城市划分为若干个区域,使得每个区域内的城市之间能够相互到达,并且划分的区域数量最少。题目提供了时间限制和内存限制,要求在给定的城市和道路信息下,计算出最少需要划分的区域数量。 ... [详细]
  • 反向投影技术主要用于在大型输入图像中定位特定的小型模板图像。通过直方图对比,它能够识别出最匹配的区域或点,从而确定模板图像在输入图像中的位置。 ... [详细]
  • DCG 创始人兼首席执行官 Barry Silbert 发布致股东信,详细解答了 19 个核心问题,并分享了公司未来的发展方向。 ... [详细]
  • 作者:守望者1028链接:https:www.nowcoder.comdiscuss55353来源:牛客网面试高频题:校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我 ... [详细]
  • 本文深入探讨了Python中的高阶函数和Lambda表达式的使用方法,结合实际案例解析其应用场景,帮助开发者更好地理解和运用这些强大的工具。 ... [详细]
  • 树链问题的优化解法:深度优先搜索与质因数分解
    本文介绍了一种通过深度优先搜索(DFS)和质因数分解来解决最长树链问题的方法。我们通过枚举树链上的最大公约数(GCD),将所有节点按其质因子分类,并计算每个类别的最长链,最终求得全局最长链。 ... [详细]
  • 问题描述:通过添加最少数量的括号,使得给定的括号序列变为合法,并输出最终的合法序列。数据范围:字符串长度不超过100。涉及算法:区间动态规划(Interval DP)。 ... [详细]
author-avatar
飞飞鱼531
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有