如何创建一个快速和放大器;庞大的工会阵列,而不使用C浪费内存吗? [英] How to create a fast & huge union array without wasting memory in C?

查看:194
本文介绍了如何创建一个快速和放大器;庞大的工会阵列,而不使用C浪费内存吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用联盟不同的数据类型存储在相同的内存。该数组有一个固定的长度,并应快速访问并须浪费少存储器尽可能

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

 的#include<&stdio.h中GT;
#包括LT&;&stdint.h GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&inttypes.h GT;#定义RESERVED_BYTES 1073741824
//#定义RESERVED_BYTES 2147483648工会的typedef {
    烧焦C [RESERVED_BYTES] // 1字节
    uint8_t有U8 [RESERVED_BYTES] // 1字节
    uint16_t U16 [RESERVED_BYTES / 2]; // 2字节
} ARRAY_TYPE;INT主要(无效)
{
    ARRAY_TYPE *阵列;
    阵=释放calloc(1,sizeof的(ARRAY_TYPE));    的getchar();
    返回0;
}

这code ++工程,并分配1GB的内存和数组的元素可以用数组[0] .u8 [3] 例如使用我知道我有,因为它们依赖于字节大小照顾指数。

可悲的是code编译失败,如果我增加内存大小(请参阅的#define RESERVED_BYTES 2147483648 ),并在64位机器上MSVS 2013我收到错误C2148:数组的总大小不得超过字节为0x7FFFFFFF 。在另一方面,它是把2GB直入释放calloc 一样,阵列=释放calloc(2147483648,sizeof的(*数组))没有问题;

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

 工会{
    焦炭℃; // 1字节
    uint8_t有U8; // 1字节
    uint16_t U16; // 2字节
} *阵列;

或需要构建计算两个指数欲避免耗时的功能:

 工会{
    焦C [2]; // 1字节
    uint8_t有U8 [2]; // 1字节
    uint16_t U16 [1]; // 2字节
} *阵列;
阵列[3] .u8 [2] = 1;

因此​​,如何处理这个问题?


解决方案

  

我想用不同的工会数据类型存储在相同的内存。该数组有一个固定的长度


由code你贴去,数组有相同的字节的-length,但持有的不同的的根据其类型元素的个数。


  

我收到一个错误C2148:数组的总大小不得超过字节为0x7FFFFFFF


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


  

但是,随着这个版本我可能会浪费内存
  结果......还是需要建立一个计算这两个指数一个耗时的功能


您可以通过略微修改联盟的定义,无记忆浪费,没有额外的访问实现(几乎)相同的效果。

 的#define RESERVED_BYTES 2147483648工会的typedef {
    无效* PV;
    字符* PC;
    uint8_t有* PU8;
    uint16_t * PU16;
} parray_type;INT主要(无效)
{
    parray_type粒子阵列;
    parray.pv =释放calloc(RESERVED_BYTES,1);    在每种类型分配的缓冲区//最后一个元素
    焦C = parray.pc [RESERVED_BYTES - 1];
    uint8_t有U8 = parray.pu8 [RESERVED_BYTES - 1];
    uint16_t U16 = parray.pu16 [RESERVED_BYTES / 2 - 1];    返回0;
}

当然,你必须永远记住,对于最大指数 PU16 是一半的PC PU8 但是这是在原来的code中的premise为好。

I'd like to store different datatypes in the same memory using union. This array has a fixed length and shall be accessed quickly and shall waste as little memory as possible.

I will define areas in which the same datatypes are stored. So I do this:

#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;
}

This code works and allocates 1GB of memory and the elements of that array can be used with array[0].u8[3] e.g. I know I have to take care of indices because they depend on the byte-size.

Sadly the code fails to compile if I increase the memory size(see #define RESERVED_BYTES 2147483648) and with MSVS 2013 on a 64bit machine I receive an error C2148: total size of array must not exceed 0x7fffffff bytes. On the other hand it is no problem to put the 2GB straight into the calloc like that array = calloc(2147483648, sizeof(*array));.

But with this version I might waste memory:

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

or need to build a time-consuming function that calculates the both indices I want to avoid:

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

So how to deal with that issue?

解决方案

I'd like to store different datatypes in the same memory using union. This array has a fixed length

Going by the code you posted, the arrays have the same byte-length, but hold different number of elements based on their type.

I receive an error C2148: total size of array must not exceed 0x7fffffff bytes.

If I were to guess, this might be related to the 2 GB limit on static data that applies even to 64-bit compiles, meaning that a union of type array_type could never be instantiated as either a global/static variable, or a local/stack one (Memory Limits for Applications on Windows). Which, in the end, means that the only choice left is to allocate such an array dynamically on the heap.

But with this version I might waste memory
...or need to build a time-consuming function that calculates the both indices

You could achieve (nearly) the same effect by slightly modifying the union definition, without memory waste and without additional accessors.

#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;
}

Of course, you'll have to always remember that the max index for pu16 is half that of pc and pu8 but that's the premise in the original code as well.

这篇关于如何创建一个快速和放大器;庞大的工会阵列,而不使用C浪费内存吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆