我所说的结构是最后一个。当我尝试使用它时会出现分段错误,当我使用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;
}
答案 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()
分配的链接列表或脚本数组,而不是保留固定数量的空间。