我想使用union
将不同的数据类型存储在同一个内存中。该阵列具有固定长度,应快速访问,并尽可能少浪费。
我将定义存储相同数据类型的区域。所以我这样做:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <inttypes.h>
#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
。另一方面,将{2}直接放入与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;
那么如何处理这个问题?
答案 0 :(得分:4)
我想使用union将不同的数据类型存储在同一个内存中。该数组具有固定长度
根据您发布的代码,数组具有相同的字节 -length,但根据其类型保存不同的数量的元素。
我收到错误C2148:数组的总大小不得超过0x7fffffff字节。
如果我猜测,这可能与静态数据的2 GB限制有关,甚至适用于64位编译,这意味着array_type
类型的联合永远不会被实例化为全局/静态变量或本地/堆栈变量(Memory Limits for Applications on 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
的最大索引是pc
和pu8
的一半,但这也是原始代码中的前提。< / p>