0

我所说的结构是最后一个。当我尝试使用它时出现分段错误,当我使用 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;
}
4

2 回答 2

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))。

这对于 a 来说是一个非常大的尺寸struct,并且很可能会使您的系统崩溃(特别是如果您在堆栈上使用它)。如果你分配几个environment_structs(在堆上),你很可能会耗尽内存。

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

编辑:是的,你在environment_struct堆栈上声明 a 。这么大的结构对堆栈来说是疯狂的。

于 2013-09-04T00:15:16.130 回答
0

Just a small addendum to Cornstalks' answer. On a 64-bit Intel system, the sizes would be, according to my calculations:

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

Therefore, the result you get from sizeof are correct.

In your code, you are putting environment_struct on the stack. The stack space is usually fixed and quite limited - on my system it's just 8 MiB. If you really want to use such a gigantic structure, you should allocate the memory for it with malloc(). A better approach, which would also remove the rather arbitrary limit of 65536 scripts, would be to store a linked list or array of scripts allocated with malloc(), instead of reserving a fixed amount of space.

于 2013-09-04T00:23:05.117 回答