C 避免对齐问题

2024-04-11

请解释一下,下面的示例到底有什么问题,特别是“这可能导致从不是四的倍数的地址加载 32 位无符号长整型”的部分:

“编译器通常会自然地防止对齐问题 对齐所有数据类型。事实上,对齐问题通常不是 内核开发人员主要关心的问题 gcc 人员必须担心 关于他们。然而,当程序员也玩的时候,问题就出现了 与指针紧密结合并访问环境外部的数据 编译器预期的。

使用更大对齐的重铸指针访问对齐地址 地址会导致对齐问题(无论这对于 特定的架构)。也就是说,这是一个坏消息:

char dog[10];
char *p = &dog[1];
unsigned long l = *(unsigned long *)p;

此示例将指向 char 的指针视为指向无符号的指针 long,这可能会导致 32 位 unsigned long 被加载 不是四的倍数的地址。

如果您在想:“我到底什么时候会这样做?”你是 也许是对的。尽管如此,它已经出现了,并且还会再次出现,所以 小心。现实世界的例子可能并不那么明显。”

虽然我不太明白这个问题,但是可以使用以下代码解决它吗?如果可以,为什么?

char * dog = (char *)malloc(10 * sizeof(char));
char *p = dog +1;
unsigned long l = *(unsigned long*)p;

你引用的这段话完全正确。

大多数时候,您不必担心对齐问题,因为编译器会为您处理它,并且效果很好,除非您做了一些奇怪的事情,以至于成功挫败了编译器保护您的尝试。

你打电话时malloc,没有问题,因为malloc很特别(在几个方面)。除此之外,它“保证返回一个指向与任何类型对象适当对齐的存储的指针”。

但是,是的,如果你努力这样做,你可能会给自己带来麻烦。回到最初的例子,假设我们有

char dog[] = "My dog Spot";
char *p = &dog[0];
unsigned long l = *(unsigned long *)p;

假设数组碰巧在内存中布局如下:

      +---+---+---+---+
100:  |   |   | M | y |
      +---+---+---+---+
104:  |   | d | o | g |
      +---+---+---+---+
108:  |   | S | p | o |
      +---+---+---+---+
112:  | t |\0 |   |   |
      +---+---+---+---+

也就是说,假设数组dog最终到达内存地址 102,该地址不是 4 的倍数。所以指针p也指向地址102,我们尝试访问long int地址 102。(你会注意到我已将其更改为&dog[0],相对于&dog[1]在最初的例子中,试图让事情变得更清楚。)

所以我们可能期望变量l最终包含 1299783780 或 1679849805 (即 0x4d792064 或 0x6420794d),因为这些是以大端或小端表示解释的前四个字节“My d”的表示。

但由于这是一次未对齐的访问,我们可能不会得到任何一个数字;该程序可能会因“总线错误”之类的问题而崩溃。

如果我们有义务并决心做这种事情,我们可以自己设法进行对齐,如下所示:

char dog[] = "My dog Spot";
char *p = dog;
int al = (intptr_t)p % sizeof(unsigned long);
al = sizeof(unsigned long) - al;
if(al == sizeof(unsigned long)) al = 0;
p += al;
unsigned long l = *(unsigned long *)p;

当然,移动指针后p直到它指向 4 的正确倍数为止,它不再指向“My d”;现在它指向“狗”。

我曾经做过一两次这样的事情,但我真的不能推荐它。

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

C 避免对齐问题 的相关文章

随机推荐

  • 无法获取某些用户的页面

    我开发了一个 PHP 应用程序 只需要获取用户是否喜欢某个页面 我这样登录用户 this gt facebook new Facebook array appId gt 123 secret gt 346 this gt facebookU
  • 在替换器中访问验证失败的值?

    当在 Laravel 中使用自定义验证规则和替换器时 我真的很难找到任何可以简单地让您获取验证失败的值的文档 例如 我创建了一个文件存在验证器 Validator extend view exists function field valu
  • 如何使用React中的map函数更改第一个元素的css?

    我正在考虑每次更新数组时仅更改数组上的第一个元素 我无法在 ReactJS 中提出任何解决方案 例如 如果我有一个来自数组的用户列表 我只想启用该用户列表中的第一个用户 您确实可以访问index参数 您可以仅将类添加到第一个元素 您只需检查
  • 警告:mysqli_query() 期望参数 1 为 mysqli 布尔值[重复]

    这个问题在这里已经有答案了 通过我的表单提交一些内容后 我得到欢迎部分 然后是 mysql 连接错误 因为 mysql 已关闭 当我打开它时它消失 然后是布尔错误 警告 mysqli query 期望参数 1 为 mysqli 布尔值在 C
  • 无需用户执行即可重置 MySQL 字段值

    我需要在午夜自动重置 MySQL 字段值 它是表中特定行中的特定列 我知道如何在 PHP 中执行此操作 但我不知道如何在午夜执行 PHP 脚本 而无需有人自己执行 您有可行的解决方案吗 编辑 最好不使用 Cron Jobs 如果你在 Lin
  • R Markdown 和 Windows 中的多行乳胶方程

    下面的代码在linux上运行良好 title LaTeX test author Ignacio output html document Latex begin aligned y j sim N theta j sigma j 2 si
  • AlarmManager 第二次过早触发 PendingIntent

    我有这个代码 设置闹钟 public void setAlarm Calendar Calendar Object Calendar getInstance Calendar Object add Calendar DAY OF YEAR
  • 如何使用 C# 最大化 Selenium WebDriver (Selenium 2) 中的浏览器窗口?

    有没有办法使用 WebDriver Selenium 2 和 C 来最大化浏览器窗口 driver Manage Window Maximize 这适用于 IE 和 Firefox Chrome 无法工作 ChromeDriver 项目上为
  • android 中 EditText 内的可点击按钮(或任何视图)

    我想在我的 EditText 中有一个按钮或可单击的视图 以便我可以在单击它时执行一些操作 我能够在我的 EditText 中放置一个可绘制对象 这要归功于马科斯贝里戈 https stackoverflow com users 18191
  • 如何从脚本中获取当前的 PHP 可执行文件?

    我想从 PHP CLI 中运行 PHP CLI 程序 在某些将运行此程序的计算机上 同时安装了 PHP 4 和 PHP 5 如果我运行外部程序 php5 outer php 我希望内部脚本使用相同的 PHP 版本运行 在 Perl 中 我会
  • 循环结束时的无限动画关键帧和 z 索引问题

    我有一些动画 最终希望能组成一个漂亮的纯 CSS 动画 基本上我将数字分成两部分 并在 X 轴上旋转 180 为这两部分设置动画 然而 由于关键帧的无限循环 我在 z 索引方面遇到了问题 在循环结束时 错误的数字位于顶部 因此短暂地显示了错
  • ASP.NET Core - 在运行时更改 JWT SecurityKey

    具有与此类似的配置 services AddAuthentication JwtBearerDefaults AuthenticationScheme AddJwtBearer x gt x TokenValidationParameter
  • 如何使用 homebrew 在 macOS 中安装早期版本的 Python 3?

    如何使用brew 在 macOS 中安装以前版本的Python 3 通过命令brew install python我获得了最新版本的 Python 3 当前为 v3 7 0 但我想要最新版本的 Python 3 6 当前为 3 6 5 我读
  • 如何将边框半径应用于具有水平滚动的分隔表格行?

    我有一个包含大量数据的表 因此必须水平滚动 我设计了将每一行分隔为每张单独卡片的表格 但我无法正确获得表格行左右部分的边框半径 如果我滚动到右端 那么我可以看到右侧的半径和左侧的半径相同 当您位于中间时 您看不到任何边界半径 PS 当存在水
  • 如何间隔重叠注释

    我想用一些文本注释图表中的条形 但如果条形靠得很近并且高度相当 则注释高于 ea 其他 因此难以阅读 注释的坐标取自条形位置和高度 如果发生碰撞 有没有办法移动其中一个 Edit 这些条非常细 有时非常接近 所以仅垂直对齐并不能解决问题 A
  • 类型错误:未定义不是构造函数

    我对 Angular 还很陌生 我仍在尝试解决其中的大部分问题 我正在使用从 Yeoman Generator 生成的 Angular 1 5 8 编写一些测试 具体来说 我试图弄清楚如何操纵 httpBackend 结果 我不确定这是否重
  • matplotlib、pyplot.annotate 的自定义箭头样式

    我正在使用 matplotlib pyplot annotate 在我的绘图上绘制箭头 如下所示 import matplotlib pyplot as plt plt annotate x ybottom x ytop arrowprop
  • 组合:使用特征来避免转发功能?

    假设我们有两个班级 A and B 当使用组合来建模时 has a or 根据 实施 关系 例如B has a A 相对于继承的缺点之一是B不包含公共功能A它需要 为了获得访问A的公共功能 需要提供转发功能 与继承相反 其中B将继承所有A的
  • WTForm“OR”条件验证器? (电子邮件或电话均可)

    class ContactForm Form name StringField Name validators DataRequired Length max 255 email StringField Email validators O
  • C 避免对齐问题

    请解释一下 下面的示例到底有什么问题 特别是 这可能导致从不是四的倍数的地址加载 32 位无符号长整型 的部分 编译器通常会自然地防止对齐问题 对齐所有数据类型 事实上 对齐问题通常不是 内核开发人员主要关心的问题 gcc 人员必须担心 关