C - 为什么在进行指针算术时转换为 uintptr_t vs char*

2024-02-26

我正在开发一个程序,我必须修改目标进程内存/读取它。

到目前为止,我使用 void* 来存储地址,如果需要更改它们,请将它们转换为 char* (一般添加偏移量或修改)

我听说过 stdint.h 中定义的该类型,但我没有看到使用它进行指针算术与 char* 转换之间的区别(至少对我来说这似乎对 C89 更友好)

所以我的问题是:我应该使用这两种方法中的哪一个来进行指针算术?在任何情况下我都应该考虑使用 uintptr_t 而不是 char* 吗?

EDIT 1

基本上我只需要知道这是否会产生

0x00F00BAA hard coded memory adress in target
process
void* x = (void*)0x00F00BAA;
char* y = (void*)0x00F00BAA;
x = (uintptr_t)x + 0x123;
y = (char*)y + 0x123;

x == y?
x == (void*)0x00F00CCD?
y == (void*)0x00F00CCD?

在评论中用户R..指出如果代码正在处理的地址在当前进程中无效,则以下内容可能不正确。我已要求 OP 进行澄清。

不使用uintptr_t如果您关心代码的可移植性,则可以使用指针算术。uintptr_t是整数类型。对它的任何算术运算都是整数算术,而不是指针算术。

如果你有一个void*值并且您想为其添加字节偏移量,转换为char*是正确的做法。

很可能算术uintptr_t值的工作方式与char*算术,但绝对不能保证。 C 标准提供的唯一保证是您可以将void*价值uintptr_t然后再返回,结果将与原始指针值进行比较。

标准并不能保证uintptr_t存在。如果没有足够宽的整数类型来保存转换后的指针值而不丢失信息,则实现将不会定义uintptr_t.

我实际上曾研究过系统(Cray 向量机),其中算术uintptr_t不一定有效。硬件有 64 位字,机器地址包含字的地址。类 Unix 操作系统需要支持 8 位字节,因此字节指针 (void*, char*)包含一个字地址,其 3 位偏移量存储在 64 位字的其他未使用的高位 3 位中。指针/整数转换只是复制表示形式。结果是a加1char*指针会导致它指向下一个字节(偏移量由软件处理),但转换为uintptr_t加 1 会导致它指向下一个word.

底线:如果需要指针算术,请使用指针算术。这就是它的用途。

(顺便说一下,gcc 有一个扩展,允许在void*。不要在可移植代码中使用它。它还会导致一些奇怪的副作用,例如sizeof (void) == 1.)

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

C - 为什么在进行指针算术时转换为 uintptr_t vs char* 的相关文章

随机推荐

  • Nexus 存储库 3 备份

    最近我安装了Nexus 存储库 3在 OpenStack Cloud 中 我已经使用它一段时间了 我想对 Nexus 执行增量备份 从而保护我们的数据 如何对 Nexus 数据进行增量备份 Nexus 备份的过程描述于文档 https he
  • 使用负年份创建 Instant

    我正在尝试创建一个Instant基于公元前公历中的年份 这是我到目前为止所拥有的 Instant FromDateTimeOffset new DateTimeOffset 1000 10 01 0 0 0 0 new System Glo
  • SwiftUI 中带有背景图像的透明导航栏

    我有一个自定义导航栏 它是一个图像 后跟标题文本 图像设置为缩放以填充 但没有完全填满导航栏 因此 您可以看到图像未覆盖的一小部分条形 我尝试将导航栏的背景颜色设置为清除 但这不起作用 有什么建议么 struct ContentView V
  • 如何通过 GPS 检查距 x,y 位置 10 米的半径

    我从 GPS 得到这个位置 40 715192 74 005795 如何判断i是否在10米半径范围内 提前致谢 使用半正矢公式http en wikipedia org wiki Haversine formula http en wiki
  • 将 yuv 序列转换为 bmp 图像

    我有 yuv 序列 我想将它们转换为 bmp 图像 我想将其保存到我的计算机上的文件夹中 我使用了 yuv2bmp m 文件这个链接 http www mathworks com matlabcentral fileexchange 255
  • 数据库 - 为什么不区分大小写?

    我看到一两个线程在全球范围内讨论区分大小写 但我的问题更具体 例如 我理解对文本值不区分大小写的搜索的兴趣 但为什么我们要使用不区分大小写的数据库名称 表和列呢 难道不会导致错误吗 使用数据库的脚本语言都是区分大小写的 因此 例如 如果我们
  • MS Graph Java SDK:如何将大文件上传到 OneDrive?

    我正在尝试从 Java 应用程序将文件上传到 OneDrive 但我不了解流程 也没有在 SKD 中看到任何用于文件上传的文档或方法 我发现的唯一流程是 driveClient me drive root createUploadSessi
  • 如何获取 DShellFolderViewEvents 的方法签名

    我试图沉沦DShellFolderViewEvents使用 ATL 我能够成功订阅的唯一方法是DISPID SELECTIONCHANGED 标题中似乎列出了许多其他事件shdispid h 但我无法让他们开火 不确定我做错了什么 可能与
  • Blogger Javascript 在帖子 > 500 上出现 JSON 错误

    我想向我的博主展示随机帖子 我从谷歌搜索得到了一个 javascript 并尝试了它 但是随机帖子的数量不正确 应该是 10 但有时是 4 有时是 2 等等 我尝试检查发生了什么 发现 json feed entry 500 抛出错误 这是
  • 为什么Restlet无法注册JSON转换器?

    我在这里束手无策 似乎从来没有遇到过这个问题 我发现设置快速 HelloWorld 应用程序以确保 Restlet 2 0 启动并运行相对容易 然而 我面临着一个我以前从未遇到过的奇怪异常 我的类路径和 WEB INF lib 文件夹中都有
  • g++:错误:libgomp.spec:没有这样的文件或目录

    我使用 g GCC 4 7 2 在 Windows 7 64 位版本上 下载自http nuwen net mingw html http nuwen net mingw html 我尝试使用 fopenmp 标志并收到错误 g 错误 li
  • Swagger/Swashbuckle 列出可接受的值?

    我已在 Web API 应用程序上成功实现了 Swashbuckle Swagger 但对输出并不满意 我的 Web api 方法之一 企业事件日志记录工具 接受复杂对象值的 JSON 对象 问题在于 当存在可以使用的可接受值的选定列表时
  • 在 Windows 上监听“使用我的 Java 应用程序打开文件”事件

    标题很混乱 但不知道如何用几句话来解释 我有一个读取 example 文件的 java 应用程序 我还添加了一个文件关联 感谢install4j因此 当用户双击任何扩展名为 example 的文件时 我的应用程序就会启动 看来 instal
  • 在 Python 脚本中以 Windows 上的不同用户(非管理员)身份运行程序

    使用以下代码 class ImpersonateWin32Sec object def init self domain username password self username username self password pass
  • 在 Vaadin 7 Web 应用程序中获取用户的 IP 地址和其他客户端信息

    In Vaadin https www Vaadin com 7 如何获得IP地址 http en wikipedia org wiki IP address用户的计算机 设备 我可以获得有关客户的其他信息吗 Vaadin WebBrows
  • Laravel - AppServiceProvider 未被调用

    我尝试在 Laravel AppServiceProvider 中绑定一些服务 但服务没有绑定 我认为 AppServiceProvider 甚至没有被调用 事实上 我做了一个新的并且有效 所以我的问题是 我做错了什么吗 或者 AppSer
  • 不带 FROM 子句的 SELECT

    我正在为我的 MS Access 数据库编写一条 SQL 语句 目的是对 3 个不同查询的值进行计数 所以我尝试了以下方法 SELECT query1 query2 query3 AS Qtd 每个查询从聚合函数计数中返回一个唯一值 即qu
  • 将小提琴图与箱线图相结合

    我有一个非常简单的数据集 2 组 每组 n 15 使用 ggplot2 我可以轻松绘制两组的小提琴图或箱线图 但是 我想绘制小提琴图 但填充阴影对应于我的数据的 3 个四分位数 有一个用SAS做的例子here http blogs sas
  • 使用 okHttp3 上传动态数量的文件

    如何管理动态数量的文件的上传OkHttp http square github io okhttp v3 我已经用旧版本的 OkHttp 实现了compile com squareup okhttp okhttp 2 6 0 类 Form
  • C - 为什么在进行指针算术时转换为 uintptr_t vs char*

    我正在开发一个程序 我必须修改目标进程内存 读取它 到目前为止 我使用 void 来存储地址 如果需要更改它们 请将它们转换为 char 一般添加偏移量或修改 我听说过 stdint h 中定义的该类型 但我没有看到使用它进行指针算术与 c