【问题标题】:Pointer alignment issue指针对齐问题
【发布时间】:2018-01-17 13:58:56
【问题描述】:

我有一个文件的内容已经加载到内存中,我想将文件中的数据分配给一组方便的结构,我不想分配新的内存。

所以我有了来自文件的数据开始的内存指针,从那里我处理这个指针,将值分配给不同的结构,但随后我到达程序崩溃的点。

//_pack_dynamic is the pointer to the data in memory
us *l_all_indexes = (us *) _pack_dynamic; //us is an unsigned short

printf("Index 0:%d", l_all_indexes[0]); //here is where the program crashes

_pack_dynamic += sizeof(us) * m_number_of_indexes;

数据,至少对于第一个元素,是存在的,我可以像这样把它拿出来:

us temp;
memcpy(&temp, _pack_dynamic, sizeof(us));

知道如何在不分配新内存的情况下从 _pack_dynamic 中提取所有索引 (m_number_of_indexes) 并将它们分配给 l_all_indexes 吗? p>

【问题讨论】:

  • 结构被打包,数据正确对齐,是吗?
  • us 是什么?为什么可以打印?我还看到一些缺少的括号。
  • 是的。我使用 little-endian 将文件打包在 python 中(它适用于 little endian 处理器)。之前,我让它处理新的内存分配,但决定摆脱它。
  • @Eugene Sh "us" 在一个无符号的缩写中,抱歉我在复制数据时错过了 printf 上的括号(代码编译)
  • 在 C++ 中这是未定义的行为,请改用 std::memcpy。它也可能是 C 中的 UB,您需要检查标准。

标签: c pointers memory-management alignment


【解决方案1】:

访问_pack_dynamic 就好像它包含us 对象具有未定义的行为,除非它确实包含这样的对象(这是一个轻微的简化,但一个很好的经验法则。char 的数组当然不能被解释为short)。

memcpy 进入正确的us 对象的方法是将内存解释为对象的唯一标准方法。整数的另一种方法是逐字符读取字符并移位掩码或将它们一起读取。这种方法允许假设特定的字节序而不是原生字节序。

一种可能有效的依赖于系统的方法是确保_pack_dynamicus 要求的边界对齐。但即便如此,标准也不能保证您的行为。

“分配”一个自动变量几乎没有任何运行时开销。为short 分配几个字节通常是微不足道的。

【讨论】:

  • 好的,感谢您的解释,我想我将不得不回到以前的版本并分配新的内存并改用 memcpy。
猜你喜欢
  • 2017-10-02
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 2017-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多