这个结构太大了吗?

时间:2013-09-04 00:05:25

标签: c struct

我所说的结构是最后一个。当我尝试使用它时会出现分段错误,当我使用sizeof来获取它的大小时会返回218369176。

typedef struct
{
unsigned long       a1; /* Last structure in group. */
unsigned long       a2; /* Next structure in group. */
char            rc; /* Representing character. */
short           st; /* Type of structure (purpose). */
short           pl; /* Privilege level required to alter. */
short           vt; /* Type of value (short, char, int, long, float, double, void*). */
union
{
    short       s;
    char        c;
    int     i;
    long        l;
    float       f;
    double      d;
    void*       p;
}           un; /* Union containing values to be stored. */
} index_struct;             /* Structure composing a table tree. */

typedef struct
{
unsigned long       sr;                             /* Script return value. */
unsigned long       ir;                             /* Interpreter return value. */
unsigned long       lc;                             /* Execution counter (text division interpreter stopped at). */
short           ai;                             /* Action identifier (current status of interpretation). */
short           pr;                             /* Script privilege information. */
char            st[65536 /* Change SCRIPT_TEXT_SIZE with this. */];     /* Segment containing script text. */
index_struct        lt[65536 /* Change LOCAL_TREE_SIZE with this. */];      /* Segment containing local tree. */
} script_struct;                                        /* Structure containing script state information and variables. */

typedef struct
{
unsigned long       us;                         /* Number of unjoined scripts. */
unsigned long       sn;                         /* Number of running scripts. */
short           es;                         /* Environment status. */
script_struct       sl[100 /* Change MAX_NUMBER_SCRIPTS with this. */]; /* Segment containing script list. */
index_struct        gt[65536 /* Change GLOBAL_TREE_SIZE with this. */]; /* Segment containing global tree. */
} environment_struct;

编辑:根据热门请求,这是整个源代码文件。

/*
 * BY:  Charles Edwin Swain the 3rd.
 * LANGUAGES:  C and (if I ever comment out certain sections of code) x86 Assembly.
 */

#include <stdio.h>

/*
#include <stdint.h>

const uint8_t CPUID_UNSPECIFIED = 0;
const uint8_t CPUID_SUPPORTED = 1;
const uint8_t CPUID_UNSUPPORTED = 2;

typedef struct
{
    uint32_t    maximum_standard_level;
    uint32_t    raw_vendorid[4];
    uint32_t    raw_processortypeORfamilyORmodelORstepping;
    uint32_t    num_extendedfamily;
    uint32_t    num_extendedmodel;
    uint32_t    num_type;
    uint32_t    num_family;
    uint32_t    
    uint32_t    raw_brandidORCLUFLUSHORCPUcountORAPICID;
    uint32_t    raw_featureflags_A;
    uint32_t    raw_featureflags_B;
    uint8_t features[64];
} CPUID_struct;
*/

/* These constants are associated with certain hard coded limits, and all must be the same to ensure proper functionality. */
const unsigned long SCRIPT_TEXT_SIZE    = 65536;    /* Size of segment containing script text. */
const unsigned long GLOBAL_TREE_SIZE    = 65536;    /* Size of segment composing global tree. */
const unsigned long LOCAL_TREE_SIZE = 65536;    /* Size of segments composing local trees. */
const unsigned long MAX_NUMBER_SCRIPTS  = 100;      /* Maximum number of running scripts in an environment. */

typedef struct
{
    unsigned long       a1; /* Last structure in group. */
    unsigned long       a2; /* Next structure in group. */
    char            rc; /* Representing character. */
    short           st; /* Type of structure (purpose). */
    short           pl; /* Privilege level required to alter. */
    short           vt; /* Type of value (short, char, int, long, float, double, void*). */
    union
    {
        short       s;
        char        c;
        int     i;
        long        l;
        float       f;
        double      d;
        void*       p;
    }           un; /* Union containing values to be stored. */
} index_struct;             /* Structure composing a table tree. */

typedef struct
{
    unsigned long       sr;                             /* Script return value. */
    unsigned long       ir;                             /* Interpreter return value. */
    unsigned long       lc;                             /* Execution counter (text division interpreter stopped at). */
    short           ai;                             /* Action identifier (current status of interpretation). */
    short           pr;                             /* Script privilege information. */
    char            st[65536 /* Change SCRIPT_TEXT_SIZE with this. */];     /* Segment containing script text. */
    index_struct        lt[65536 /* Change LOCAL_TREE_SIZE with this. */];      /* Segment containing local tree. */
} script_struct;                                        /* Structure containing script state information and variables. */

typedef struct
{
    unsigned long       us;                         /* Number of unjoined scripts. */
    unsigned long       sn;                         /* Number of running scripts. */
    short           es;                         /* Environment status. */
    script_struct       sl[100 /* Change MAX_NUMBER_SCRIPTS with this. */]; /* Segment containing script list. */
    index_struct        gt[65536 /* Change GLOBAL_TREE_SIZE with this. */]; /* Segment containing global tree. */
} environment_struct;                                   /* Structure containing environment state information and global tree. */

/*
 * Function definition and calling conventions follow:
 *
 *  - All non-interpreter functions should be called through a wrapper function.
 *  - This wrapper function's address is specified through the p field of an index_struct in the global tree.
 *  - The return items of the function are specified through the global tree, under 'f_retu'.
 *  - The arguments to the function are specified through the global tree, under 'f_argv'.
 *  - The number of arguments to the function are specified through the global tree, under 'f_argc'.
 *  - Before calling the wrapper function, these fields and the environment status are appropriately set.
 *  - The wrapper function takes a pointer to the segment containing the global tree as an argument (outside the interpreter).
 *  - The wrapper function sorts through the arguments and calls the appropriate function it is wrapping.
 *  - Once this function returns, it sets any actual interpreter buffers accordingly.
 *  - What is meant by the above is that the wrapper function will use temporary buffers in the call to the function, then transfer data over according to global tree arguments.
 *  - Once the wrapper function returns, the calling (interpreter) code should copy all data from the return to an appropriate location and wipe all involved tables (for security).
 *  - This entire state is uninterruptable by interruption code from the moment the interpreter begins the call to after the interpreter finishes wiping data.
 *  - The above does not include signals, and only describes with regard to the interpreter auto returning after interpreting some input.
 *
 */

/* Creates a fresh interpreter environment. */
int ecreate(environment_struct* environment)
{
    if (environment == NULL)
    {
        return -1;
    }
    else
    {
        if (environment->es != 0)
        {
            return -2;
        }
        else
        {
            environment->us = 0;
            environment->sn = 0;
            environment->es = 1;
            return 0;
        }
    }
}

/* Cleans up and shuts down an interpreter environment. */
int edestroy(environment_struct* environment)
{
    if (environment == NULL)
    {
        return -1;
    }
    else
    {
        if (environment->es == 0)
        {
            return -2;
        }
        else
        {
            environment_struct environment_B;
            *environment = environment_B;
            return 0;
        }
    }
}

/* Main function. */
int main(int argc, char** argv)
{
/* This is where the sizeof is.  Works fine when code behind next comment is not commented in.*/
    printf("%lu\n", sizeof(environment_struct));
/* Next comment. */
    environment_struct environment;
    int r_ecreate, r_edestroy;
    r_ecreate   = ecreate(&environment);
    r_edestroy  = edestroy(&environment);
    printf("%d, %d\n", r_ecreate, r_edestroy);
    return 0;
}

2 个答案:

答案 0 :(得分:4)

index_struct在平均32位系统上的大小为24字节(或者在平均64位系统上为32字节)。

script_struct在平均32位系统上的大小为1,638,416字节(1.6 MB)(或者在平均64位系统上为2,162,720字节(2.16 MB))。

environment_struct在您的平均32位系统上的大小为165,414,476(165.4 MB)(或者在您的平均64位系统上为218,369,176字节(218.3 MB)(这是您所看到的大小) )。

对于struct来说,这是一个疯狂的大尺寸,很可能会使您的系统崩溃(特别是如果您在堆栈中使用它)。如果你在堆上分配了几个environment_struct,那么你的内存就会很短。

所以是的,它们太大了。 Waaay太大了。

编辑:是的,你在堆栈上声明environment_struct。一个大的结构对于堆栈是疯狂的。

答案 1 :(得分:0)

只是Cornstalks回答的一个小附录。根据我的计算,在64位Intel系统上,大小将是:

sizeof(index_struct) = 32
sizeof(script_struct) = 2162716
sizeof(environment_struct) = 218368770

因此,您从sizeof获得的结果是正确的。

在您的代码中,您将environment_struct放在堆栈上。堆栈空间通常是固定的并且非常有限 - 在我的系统上它只有8 MiB。如果你真的想要使用这样一个巨大的结构,你应该用malloc()为它分配内存。一种更好的方法,也可以删除65536脚本的相当任意限制,即存储用malloc()分配的链接列表或脚本数组,而不是保留固定数量的空间。