如何创建一个快速和巨大的联合数组而不浪费C中的内存?

我想使用union将不同的数据类型存储在同一个内存中。 该arrays具有固定长度,应快速访问,并尽可能少浪费内存。

我将定义存储相同数据类型的区域。 所以我这样做:

 #include  #include  #include  #include  #define RESERVED_BYTES 1073741824 //#define RESERVED_BYTES 2147483648 typedef union { char c[RESERVED_BYTES]; //1Byte uint8_t u8[RESERVED_BYTES]; //1Byte uint16_t u16[RESERVED_BYTES / 2]; //2Byte } array_type; int main(void) { array_type *array; array = calloc(1, sizeof(array_type)); getchar(); return 0; } 

这段代码工作并分配1GB内存,该数组的元素可以与array[0].u8[3]例如我知道我必须处理索引,因为它们依赖于字节大小。

遗憾的是,如果我增加内存大小(参见#define RESERVED_BYTES 2147483648 )并且在64位计算机上使用MSVS 2013,则代码无法编译我收到error C2148: total size of array must not exceed 0x7fffffff bytes 。 另一方面,将2GB直接放入calloc就没有问题,就像array = calloc(2147483648, sizeof(*array));

但是对于这个版本,我可能会浪费内存:

 union { char c; //1Byte uint8_t u8; //1Byte uint16_t u16; //2Byte } *array; 

或者需要构建一个耗时的函数来计算我想要避免的两个索引:

 union { char c[2]; //1Byte uint8_t u8[2]; //1Byte uint16_t u16[1]; //2Byte } *array; array[3].u8[2] = 1; 

那么如何处理这个问题呢?

我想使用union将不同的数据类型存储在同一个内存中。 该arrays具有固定长度

按照您发布的代码,数组具有相同的字节长度,但根据其类型保持不同数量的元素。

我收到错误C2148:数组的总大小不得超过0x7fffffff字节。

如果我猜测,这可能与静态数据的2 GB限制有关,甚至适用于64位编译,这意味着array_type类型的联合永远不能被实例化为全局/静态变量或本地/堆栈一( Windows上的应用程序的内存限制 )。 最后,这意味着剩下的唯一选择是在堆上动态分配这样的数组。

但是对于这个版本,我可能会浪费内存
……或者需要构建一个耗时的函数来计算两个索引

您可以通过稍微修改union定义来实现(几乎)相同的效果,而不会浪费内存并且无需额外的访问器。

 #define RESERVED_BYTES 2147483648 typedef union { void *pv; char *pc; uint8_t *pu8; uint16_t *pu16; } parray_type; int main(void) { parray_type parray; parray.pv = calloc(RESERVED_BYTES, 1); // last element in allocated buffer for each type char c = parray.pc[RESERVED_BYTES - 1]; uint8_t u8 = parray.pu8[RESERVED_BYTES - 1]; uint16_t u16 = parray.pu16[RESERVED_BYTES / 2 - 1]; return 0; } 

当然,你必须要记住, pu16的最大索引是pcpu8一半,但这也是原始代码的前提。