可以使用初始或终端 malloc 缓冲区吗?

2024-02-27

假设我做了如下事情:

size_t length = 1000;
char* p = malloc(length);

然后我想循环遍历元素,所以最基本的是:

for (size_t i = 0; i < length; ++i) {
  p[i] = ...; // or p[length - 1 - i] = ...
}

但也有可能是

char* q = p;
for (size_t i = 0; i < length; ++i) {
  *q = ...;
  ++q;
}

或相反

char* q = p + (length - 1);
for (size_t i = 0; i < length; ++i) {
  *q = ...;
  --q;
}

我的问题是,如果我想避免i并执行以下操作:

char* const final = p + (length - 1);
for (char* q = p; q <= final; ++q) {
  *q = ...;
}

或相反:

char* const final = p + (length - 1);
for (char* q = final; q >= p; --q) {
  *q = ...;
}

似乎在这些循环中出现错误行为的可能性非常小,以避免i;对于第一个循环,如果p + length == 0,即我们有一个系统,我们在可能的末尾分配了内存size_t发生了限制和溢出...对于第二个循环,如果p == 0,即我们有一个系统,我们在内存的开头分配了内存...在这两种情况下,循环都不会在需要时结束...

也许这些并没有真正发生,但如果这是未定义的行为,那么也许最好用循环i虽然看起来稍微不太优雅..


编辑:在 Fe2O3 的评论之后,我记得我确实想以不同的方式问它。也就是说,我不想要一个数组chars,而是某种结构类型的元素数组,因此该结构可能相对较大,大小3000, 说。那么就足够了p to be < 3000为了使第二个循环失败,没有必要将其0。另外,这也足够了final为最大尺寸减去3000... 当然,3000还可以更大...


TL;DR:递增指针版本可以,但递减指针版本未定义。

C 标准将数组中的指针算术定义为有效,只要结果指针指向 arrar 的元素或指向“末尾的一个”。在这种特殊情况下,您会得到一个无法取消引用的有效指针(这样做是未定义的),但它始终会比指向数组任何元素的任何指针大

6.5.6.8当一个整数类型的表达式与指针相加或相减时, 结果具有指针操作数的类型。如果指针操作数指向一个元素 一个数组对象,并且数组足够大,结果指向从 原始元素,使得结果和原始元素的下标之差 数组元素等于整数表达式。换句话说,如果表达式 P 指向 数组对象的第 i 个元素,表达式 (P)+N(等效于 N+(P))和 (P)-N(其中 N 的值为 n)分别指向第 i+n 个和第 i−n 个元素 数组对象,前提是它们存在。此外,如果表达式 P 指向最后一个 数组对象的元素,表达式 (P)+1 指向最后一个元素 数组对象,如果表达式 Q 指向数组对象的最后一个元素, 表达式 (Q)-1 指向数组对象的最后一个元素。如果两个指针 操作数和结果指向同一个数组对象的元素,或者指向最后一个元素 数组对象的元素,求值不得产生溢出;否则, 行为未定义。如果结果指向数组对象的最后一个元素,则它 不得用作所求值的一元 * 运算符的操作数。

因此,当您递增指针时,当您越过数组末尾时,您将得到这个特殊的“越过末尾”指针,该指针将比指向最后一个元素的指针大,并且循环将终止。然而,使用递减循环,在到达第一个元素后,您将再次递减指针并“下溢”,从而给出未定义的行为。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

可以使用初始或终端 malloc 缓冲区吗? 的相关文章

  • 如何从 C# 中的 dataTable.Select( ) 查询中删除单引号?

    所以我有一个经销商名称列表 我正在我的数据表中搜索它们 问题是 一些傻瓜必须被命名为 Young s 这会导致错误 drs dtDealers Select DealerName dealerName 所以我尝试替换字符串 尽管它对我不起作
  • 适合初学者的良好调试器教程[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有谁知道一个好的初学者教程 在 C 中使用调试器 我感觉自己好像错过了很多 我知道怎么做 单步执行代码并查看局部变量 虽然这常常给我带来问
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • 如何在C(Linux)中的while循环中准确地睡眠?

    在 C 代码 Linux 操作系统 中 我需要在 while 循环内准确地休眠 比如说 10000 微秒 1000 次 我尝试过usleep nanosleep select pselect和其他一些方法 但没有成功 一旦大约 50 次 它
  • 当一组凭据下的计划任务启动的进程在另一组凭据下运行另一个程序时,Windows 是否有限制

    所以我有一个简单的例子 其中我有应用程序 A 它对用户 X 本地管理员 有一些硬编码的凭据 然后它使用硬编码的绝对路径启动带有这些凭据的应用程序 B A 和 B 以及 dotnet 控制台应用程序 但是它们不与控制台交互 只是将信息写入文件
  • 从同一个类中的另一个构造函数调用构造函数

    我有一个带有两个构造函数的类 C 这是代码片段 public class FooBar public FooBar string s constructor 1 some functionality public FooBar int i
  • 从客户端访问 DomainService 中的自定义对象

    我正在使用域服务从 Silverlight 客户端的数据库中获取数据 在DomainService1 cs中 我添加了以下内容 EnableClientAccess public class Product public int produ
  • Python 属性和 Swig

    我正在尝试使用 swig 为一些 C 代码创建 python 绑定 我似乎遇到了一个问题 试图从我拥有的一些访问器函数创建 python 属性 方法如下 class Player public void entity Entity enti
  • C# 存档中的文件列表

    我正在创建一个 FileFinder 类 您可以在其中进行如下搜索 var fileFinder new FileFinder new string C MyFolder1 C MyFolder2 new string
  • 类型约束

    我有以下类层次结构 class Header IEnumerable
  • 为什么从字典中获取时会得到 Action<> 的克隆?

    我有以下字典 private Dictionary
  • 在 NaN 情况下 to_string() 可以返回什么

    我使用 VS 2012 遇到了非常令人恼火的行为 有时我的浮点数是 NaN auto dbgHelp std to string myFloat dbgHelp最终包含5008角色 你不能发明这个东西 其中大部分为0 最终结果是 0 INF
  • 如何在 C 中安全地声明 16 位字符串文字?

    我知道已经有一个标准方法 前缀为L wchar t test literal L Test 问题是wchar t不保证是16位 但是对于我的项目 我需要16位wchar t 我还想避免通过的要求 fshort wchar 那么 C 不是 C
  • 高效列出目录中的所有子目录

    请参阅迄今为止所采取的建议的编辑 我正在尝试使用 WinAPI 和 C 列出给定目录中的所有目录 文件夹 现在我的算法又慢又低效 使用 FindFirstFileEx 打开我正在搜索的文件夹 然后我查看目录中的每个文件 使用 FindNex
  • 从迭代器外部将 StopIteration 发送到 for 循环

    有几种方法可以打破一些嵌套循环 他们是 1 使用中断 继续 for x in xrange 10 for y in xrange 10 print x y if x y gt 50 break else continue only exec
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • 打印大型 WPF 用户控件

    我有一个巨大的数据 我想使用 WPF 打印 我发现WPF提供了一个PrintDialog PrintVisual用于打印派生的任何 WPF 控件的方法Visual class PrintVisual只会打印一页 因此我需要缩放控件以适合页面
  • C++ new * char 不为空

    我有一个问题 我在 ASIO 中开发服务器 数据包采用尖头字符 当我创建新字符时 例如char buffer new char 128 我必须手动将其清理为空 By for int i 0 i lt 128 i buffer i 0x00
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • GCC 的“-Wl,option”和“-Xlinker option”语法之间有区别吗?

    我一直在查看一些配置文件 并且看到它们都被使用 尽管在不同的体系结构上 如果您在 Linux 机器上使用 GCC 将选项传递给链接器的两种语法之间有区别吗 据我所知 阅读 GCC 手册时 他们的解释几乎相同 From man gcc Xli

随机推荐