c - 使用 C 将 u64 的数组重新解释为 u16 的 3D,而无需更改内存分配

标签 c arrays memory memory-management

我很困惑,我有一个指向无符号 64 位整数数组的指针。每个 64 位整数实际上代表 16 位整数,因此应将其拆分为 16 位数组,例如:

36348941 应该输出为:

0,0,554,41997

但是在 C 中我看不到执行此类型转换的方法。我知道 C 在内存管理方面有很大的潜力,我希望我不必为了执行此操作而遍历数据,而只需更改数据在内存中的解释方式,让处理器分配和取消分配内存对我的程序来说会很耗时(它需要尽可能快地运行 - 最好少于 20 毫秒)。

如果我简单地说:

arg1 = *(unsigned short (*))(&arg2);

我发现数据已截断了位,因此每 64 位整数仅吐出一个值,在上述情况下为 41997。

这只是应用程序另一个棘手问题的第一部分,接下来需要将这个 16 位值的数组转换为三维数组,而我可以通过以下方式编译该程序:

const int I = 4;
const int J = 256;
const int K = 256;
arg1 = *(unsigned short (*)[I][J][K])(&arg2);

但这没有给我任何数据,我在其他语言中看到过这项工作,但他们重新分配内存,因此很耗时,最好我希望所有这些都发生在处理器中,不需要内存分配,因为它是只要求内存中位的映射不同,而不是数据本身。

然后我需要能够将此数据作为指向三维数组的指针传回。这样做的原因是我正在使用的实现此目的的语言如上所述,内存分配,但调用 C DLL 的开销非常小,因此似乎有可能成为一个解决方案。

我也研究过 Unions,但我现在明白这是使用 Unions 的不正确方式。

我已经很多年没有接触过 C 了,所以非常感谢任何帮助。

最佳答案

首先,您不能使用 uint16_t * 或类似的东西来执行此操作。这是因为严格的别名规则:如果内存最初是通过某种类型写入的(有一个简短的异常(exception)列表),则只允许通过某种类型的表达式访问内存。

如果您确实想这样做,您还必须依靠编译器扩展来编译类似 C 的语言,但没有严格的别名规则,例如带有开关 -fno-strict-aliasing 的 gcc。

更便携的方法是使用 union :

union U
{
    uint64_t a[10][10];
    uint16_t b[10][40];
};

union 取代了严格的别名规则;您可以将数据写入a 并从b 中读出。

当然,输出的顺序会因平台而异。

关于c - 使用 C 将 u64 的数组重新解释为 u16 的 3D,而无需更改内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34480499/

相关文章:

c - 使用指向结构的指针或引用

c - 如何使用 c 将数组作为指针传递给函数来排序?

ios - 仅在需要时加载图像

javascript - sort() 在 mozilla 和 opera 中无法正常工作

php - PHP 中的数组组合

hadoop - 在没有 mapred-site.xml 的情况下设置 hadoop mapreduce 大小

perl - 计算数百 GB 数据中的子序列

c - (c) 中不兼容指针类型的赋值

c++ - 无符号与有符号整数的性能

c - FOTA : How can i do firmware update over the air?