473,715 Members | 6,082 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Defining the fields of a structure at run-time

I am facing this problem....
I have to define a structure at runtime as the user specifies...

The user will tell the number of fields,the actual fields...(maybe
basic or array types or multiple arrays,etc)

I do not understand how to define the structure at run time.i.e.what
fields it will contain.
Creating the field variables at run time is fine...but defining the
structure so as to contain these fields is where the problem lies...

I thought of unions within the structure representing each possible
field variable...
but again only one of these unions can exist at time...array of unions
again similar problem.

Any possible solution occuring to any one...please do let me know as
early as possible.
Thanks a lot...

Nisha.

Feb 8 '06 #1
10 2126
na************* @gmail.com wrote:
I have to define a structure at runtime as the user specifies...
Are you, perchance, writing a compiler? ;-)
The user will tell the number of fields,the actual fields...(maybe
basic or array types or multiple arrays,etc)

I do not understand how to define the structure at run time.i.e.what
fields it will contain.
Creating the field variables at run time is fine...but defining the
structure so as to contain these fields is where the problem lies...


I don't think you can do it the way you expect (if I got you right).

You could, however, allocate as much memory as the user data requires in
total. By carefully moving a char pointer around, and judiciously
casting, you can achieve your goal. I must warn you though, that this
is extremely bug-prone, and the bugs you create will be a nightmare to
fix. You'll also need an inordinate amount of book-keeping.
--
BR, Vladimir

Mickey Mouse wears a Spiro Agnew watch.

Feb 8 '06 #2
na************* @gmail.com wrote:
I am facing this problem....
I have to define a structure at runtime as the user specifies...

The user will tell the number of fields,the actual fields...(maybe
basic or array types or multiple arrays,etc)

I do not understand how to define the structure at run time.i.e.what
fields it will contain.
Creating the field variables at run time is fine...but defining the
structure so as to contain these fields is where the problem lies...

I thought of unions within the structure representing each possible
field variable...
but again only one of these unions can exist at time...array of unions
again similar problem.

Any possible solution occuring to any one...please do let me know as
early as possible.
Thanks a lot...


You cannot construct a run-time "struct" type.
What you can do, is keeping a dynamic "array" the elements of
which contain "struct member" like information, e.g.

struct memberdata {
datatype_t type;
#ifdef USES_FLAT_TYPES
size_t number;
int isScalar;
#endif
const char * membername;
void * memberdata;
};

where we have

#ifdef USES_FLAT_TYPES
typedef enum EMemberType {
EMT_invalid,
EMT_signedchar,
EMT_unsignedcha r,
EMT_char,
EMT_signedshort ,
EMT_unsignedsho rt,
EMT_signedint,
....
EMT_voidpointer ,
EMT_signedcharp ointer,
....
} datatype_t;
#endif

The above enables us to have a couple of "cheap" basic
types and derived types and arrays thereof. The isScalar is
intended to give the difference between "array 1 of Type"
and "Type".
membername always points to an array of char of size
strlen(memberna me)+1.

Now, you have to make sure that no membername is used twice,
that you access every piece of data according to type, and so
on.

This gives enough of the nightmarish bookkeeping Vladimir S. Oka
mentioned.

If you want to be able to construct arbitrary derived types,
datatype_t has to be much more complex. You can make some things
easier in some respect for you by always using
long double/long/unsigned long (or long double/intmax_t/uintmax_t
in C99) to store the values. On the other hand this requires
range checking in other places to correctly simulate overflow or
complain in time about invalid values.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Feb 8 '06 #3
Vladimir S. Oka wrote:
na************* @gmail.com wrote:
I have to define a structure at runtime as the user specifies...
Are you, perchance, writing a compiler? ;-)
The user will tell the number of fields,the actual fields...(maybe
basic or array types or multiple arrays,etc)

I do not understand how to define the structure at run time.i.e.what
fields it will contain.
Creating the field variables at run time is fine...but defining the
structure so as to contain these fields is where the problem lies...


I don't think you can do it the way you expect (if I got you right).

You could, however, allocate as much memory as the user data requires in
total. By carefully moving a char pointer around, and judiciously
casting, you can achieve your goal.


You also have to watch out for alignment issues.
I must warn you though, that this
is extremely bug-prone, and the bugs you create will be a nightmare to
fix. You'll also need an inordinate amount of book-keeping.


This is why assuming there are a finite number of types the user can
specify and given that memory efficiency is not an issue I would do
something like this:
enum field_types { SHORT, INT, LONG, TEXT };
union field_union {
short s;
int i;
long l;
char *t;
};
struct field {
enum field_types type;
union field_union val;
};

Then you can use malloc & friends to manage dynamic arrays of the field
struc.

You have a bit more work to do for TEXT, since you would obviously have
to allocate the space for the string as well. However, it avoids the
need to mess about with char pointers and casting (casting is generally
a sign you are entering dangerous territory, but it is sometimes required).
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Feb 8 '06 #4
Well, here is something i wrote some time ago, when i had a similar problem:

Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5. int count;
  6.  
  7. /*Pointer to allocated space for struct data*/
  8. char *a;
  9. /*Number of struct members*/
  10. unsigned int struct_members;
  11. /*Array containing members' size*/
  12. unsigned int *member_size;
  13. /*Array containing members' offset in allocated space*/
  14. unsigned int *member_offset;
  15. /*Allocated space size*/
  16. int total_size=0;
  17.  
  18. /*Example*/
  19. int  i=10;
  20. char k='a';
  21. struct_members=2;
  22.  
  23. /*Allocate space for member_size array*/
  24. member_size = malloc(struct_members*sizeof(*member_size));
  25.  
  26. /*For this example*/
  27. member_size[0]=2;
  28. member_size[1]=1;
  29.  
  30. /*Fill in member_size array*/
  31. for (count=0;count<struct_members;count++)
  32. total_size+=member_size[count];
  33.  
  34. /*Allocate and fill in member_offset array*/
  35. member_offset = malloc(struct_members*sizeof(*member_offset));
  36. member_offset[0]=0;
  37. for (count=1;count<struct_members;count++)
  38. member_offset[count]=member_offset[count-1]+member_size[count];
  39.  
  40. /*Allocate struct space*/
  41. a = malloc(total_size);
  42.  
  43. /*Copy example values in the proper place*/
  44. memcpy(a+member_offset[0],&i,sizeof(i));
  45. memcpy(a+member_offset[1],&k,sizeof(k));
  46.  
  47. /*Print for test purposes*/
  48. printf("Integer is: %d\n",*(a+member_offset[0]));
  49. printf("Character is: %c\n",*(a+member_offset[1]));
  50.  
  51. getchar();
  52. return 0;
  53. }
  54.  
<na************ *@gmail.com> wrote in message
news:11******** **************@ g47g2000cwa.goo glegroups.com.. .
I am facing this problem....
I have to define a structure at runtime as the user specifies...

The user will tell the number of fields,the actual fields...(maybe
basic or array types or multiple arrays,etc)

I do not understand how to define the structure at run time.i.e.what
fields it will contain.
Creating the field variables at run time is fine...but defining the
structure so as to contain these fields is where the problem lies...

I thought of unions within the structure representing each possible
field variable...
but again only one of these unions can exist at time...array of unions
again similar problem.

Any possible solution occuring to any one...please do let me know as
early as possible.
Thanks a lot...

Nisha.

Feb 8 '06 #5
stathis gotsis wrote:
Well, here is something i wrote some time ago, when i had a similar problem:
Please don't top post. Your reply belongs under the text you are
replying to (after appropriate snippage) not above.
[code]
#include <stdio.h>

int main(void)
{
int count;

/*Pointer to allocated space for struct data*/
char *a;
/*Number of struct members*/
unsigned int struct_members;
/*Array containing members' size*/
unsigned int *member_size;
/*Array containing members' offset in allocated space*/
unsigned int *member_offset;
/*Allocated space size*/
int total_size=0;

/*Example*/
int i=10;
char k='a';
struct_members= 2;

/*Allocate space for member_size array*/
member_size = malloc(struct_m embers*sizeof(* member_size));
If the compiler does not complain here it is broken. If it does you
should have fixed it. The correct fix is in #include <stdlib.h>
/*For this example*/
member_size[0]=2;
member_size[1]=1;
Bad example. On many systems these days int is 4 bytes. You should be
using sizeof the appropriate variable.
/*Fill in member_size array*/
for (count=0;count< struct_members; count++)
total_size+=mem ber_size[count];

/*Allocate and fill in member_offset array*/
member_offset = malloc(struct_m embers*sizeof(* member_offset)) ;
member_offset[0]=0;
for (count=1;count< struct_members; count++)
member_offset[count]=member_offset[count-1]+member_size[count];
So when count is 1 you get:
member_offset[1]=member_offset[0]+member_size[1]
which is
member_offset[1]=0+1
which is
member_offset[1]=1
When, since the fist element (according to you, but not if I built it on
any system I currently have access to) should be 2 to place it after the
first element instead of overlapping with it.
/*Allocate struct space*/
a = malloc(total_si ze);

/*Copy example values in the proper place*/
memcpy(a+member _offset[0],&i,sizeof(i) );
memcpy(a+member _offset[1],&k,sizeof(k) );
Since, on all my systems, sizeof(int) is 4 not 2 this will do very bad
things.
/*Print for test purposes*/
printf("Integer is: %d\n",*(a+membe r_offset[0]));
printf("Charact er is: %c\n",*(a+membe r_offset[1]));
This, in the general case, will not work, since you are completely
ignoring alignment requirements. If using this type of approach you have
to use memcpy to copy the data out in to a suitable variable data
(except for character types) before using it.
getchar();
return 0;
}


<snip problem description which should have been above your response>
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Feb 9 '06 #6
Flash Gordon wrote:
Vladimir S. Oka wrote:
This is why assuming there are a finite number of types the user can
specify and given that memory efficiency is not an issue I would do
something like this:
enum field_types { SHORT, INT, LONG, TEXT };
union field_union {
short s;
int i;
long l;
char *t;
};
struct field {
enum field_types type;
union field_union val;
};

Then you can use malloc & friends to manage dynamic arrays of the
field struc.

You have a bit more work to do for TEXT, since you would obviously
have to allocate the space for the string as well. However, it avoids
the need to mess about with char pointers and casting (casting is
generally a sign you are entering dangerous territory, but it is
sometimes required).


A much better solution yes. I also happened to think of something along
the same lines, but OP had as well (I wrongly snipped that bit):
na************* @gmail.com wrote:
I thought of unions within the structure representing each possible
field variable...


He didn't sound happy about it so I offered an alternative -- ugly as it
was. ;-)
--
BR, Vladimir

In America, any boy may become president and I suppose that's just one
of the risks he takes.
-- Adlai Stevenson

Feb 9 '06 #7
"Flash Gordon" <sp**@flash-gordon.me.uk> wrote in message
news:5h******** ****@news.flash-gordon.me.uk...
stathis gotsis wrote:
Well, here is something i wrote some time ago, when i had a similar problem:

Please don't top post. Your reply belongs under the text you are
replying to (after appropriate snippage) not above.


Thank you for taking the time to do these corrections and i will take
that into account in the future.
[code]
#include <stdio.h>

int main(void)
{
int count;

/*Pointer to allocated space for struct data*/
char *a;
/*Number of struct members*/
unsigned int struct_members;
/*Array containing members' size*/
unsigned int *member_size;
/*Array containing members' offset in allocated space*/
unsigned int *member_offset;
/*Allocated space size*/
int total_size=0;

/*Example*/
int i=10;
char k='a';
struct_members= 2;

/*Allocate space for member_size array*/
member_size = malloc(struct_m embers*sizeof(* member_size));


If the compiler does not complain here it is broken. If it does you
should have fixed it. The correct fix is in #include <stdlib.h>


My mistake, i copy-pasted from line 3:
"#include <stdlib.h>
#include <string.h>" should have preceded.
/*For this example*/
member_size[0]=2;
member_size[1]=1;


Bad example. On many systems these days int is 4 bytes. You should be
using sizeof the appropriate variable.


True as well.
/*Fill in member_size array*/
for (count=0;count< struct_members; count++)
total_size+=mem ber_size[count];

/*Allocate and fill in member_offset array*/
member_offset = malloc(struct_m embers*sizeof(* member_offset)) ;
member_offset[0]=0;
for (count=1;count< struct_members; count++)
member_offset[count]=member_offset[count-1]+member_size[count];


So when count is 1 you get:
member_offset[1]=member_offset[0]+member_size[1]
which is
member_offset[1]=0+1
which is
member_offset[1]=1
When, since the fist element (according to you, but not if I built it on
any system I currently have access to) should be 2 to place it after the
first element instead of overlapping with it.


I did not fully understand this. I suppose this derives from the fact that i
supposed sizeif(int) is 2 in any system?
/*Allocate struct space*/
a = malloc(total_si ze);

/*Copy example values in the proper place*/
memcpy(a+member _offset[0],&i,sizeof(i) );
memcpy(a+member _offset[1],&k,sizeof(k) );


Since, on all my systems, sizeof(int) is 4 not 2 this will do very bad
things.


That same mistake propagates.
/*Print for test purposes*/
printf("Integer is: %d\n",*(a+membe r_offset[0]));
printf("Charact er is: %c\n",*(a+membe r_offset[1]));


This, in the general case, will not work, since you are completely
ignoring alignment requirements. If using this type of approach you have
to use memcpy to copy the data out in to a suitable variable data
(except for character types) before using it.


I see, will that generally work instead:
"printf("Intege r is: %d\n", *((int *)(a+member_off set[0])));" ? Please shed
some more light on this.
getchar();
return 0;
}


<snip problem description which should have been above your response>
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.

Feb 9 '06 #8
stathis gotsis wrote:
"Flash Gordon" <sp**@flash-gordon.me.uk> wrote in message
news:5h******** ****@news.flash-gordon.me.uk...
stathis gotsis wrote:
Well, here is something i wrote some time ago, when i had a similar problem:
Please don't top post. Your reply belongs under the text you are
replying to (after appropriate snippage) not above.


Thank you for taking the time to do these corrections and i will take
that into account in the future.


Thank you.

<snip>
/*For this example*/
member_size[0]=2;
member_size[1]=1;

Bad example. On many systems these days int is 4 bytes. You should be
using sizeof the appropriate variable.


True as well.
/*Fill in member_size array*/
for (count=0;count< struct_members; count++)
total_size+=mem ber_size[count];

/*Allocate and fill in member_offset array*/
member_offset = malloc(struct_m embers*sizeof(* member_offset)) ;
member_offset[0]=0;
for (count=1;count< struct_members; count++)
member_offset[count]=member_offset[count-1]+member_size[count];

So when count is 1 you get:
member_offset[1]=member_offset[0]+member_size[1]
which is
member_offset[1]=0+1
which is
member_offset[1]=1
When, since the fist element (according to you, but not if I built it on
any system I currently have access to) should be 2 to place it after the
first element instead of overlapping with it.


I did not fully understand this. I suppose this derives from the fact that i
supposed sizeif(int) is 2 in any system?


The fundamental problem in this part is nothing to do with the size of
an int.

In your code you store the size of the first item in member_size[0] and
its offset (which is 0) in member_offset[0]. Given that the first member
takes two bytes, that would be a[0] and a[1]. So to calculate the
position of the second item you need to take the offset of the first
item and add the size of the first item, where as you were adding the
size of the second item. I.e., you should have:

member_offset[count]=member_offset[count-1]+member_size[count-1];

<snip>
/*Print for test purposes*/
printf("Integer is: %d\n",*(a+membe r_offset[0]));
printf("Charact er is: %c\n",*(a+membe r_offset[1]));

This, in the general case, will not work, since you are completely
ignoring alignment requirements. If using this type of approach you have
to use memcpy to copy the data out in to a suitable variable data
(except for character types) before using it.


I see, will that generally work instead:
"printf("Intege r is: %d\n", *((int *)(a+member_off set[0])));" ? Please shed
some more light on this.


Actually, I've just realised that I had miss-read what you initially
posted, so what I said it not actually quite true, although there was
still a problem.

Your original line:
printf("Integer is: %d\n",*(a+membe r_offset[0]));
will print one byte of the first member, since a is an array of char.
Obviously this is not what you want.

Your suggestion of
printf("Integer is: %d\n", *((int *)(a+member_off set[0])));
has potentially bigger problems.

Some real systems have alignment requirements for various types, so if
you try to read a 2 byte integer from an odd address they will generate
an error (often called a "bus error" or SIGBUS) and abort your program.
Since as far as the compiler is concerned a is an array of char (and
char does not have any alignment requirements) a could start on an odd
address. So casting it to an int* then dereferencing it could crash your
program (the C standard allows this).

So what you have to do is the reverse of when you put the data in. I.e.:
memcpy(i, a+member_offset[0], member_size[0]);
printf("Integer is: %d\n", i);
Ideally you should add at least basic error trapping, i.e.
if (member_size[0] != sizeof i)
fputs("ERROR: Size miss-match!\n");
else {
memcpy(i, a+member_offset[0], member_size[0]);
printf("Integer is: %d\n", i);
}
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Feb 9 '06 #9

"Flash Gordon" <sp**@flash-gordon.me.uk> wrote in message
news:mq******** ****@news.flash-gordon.me.uk...
member_offset[count]=member_offset[count-1]+member_size[count-1];
Yes of course, careless writing.
Some real systems have alignment requirements for various types, so if
you try to read a 2 byte integer from an odd address they will generate
an error (often called a "bus error" or SIGBUS) and abort your program.
Since as far as the compiler is concerned a is an array of char (and
char does not have any alignment requirements) a could start on an odd
address. So casting it to an int* then dereferencing it could crash your
program (the C standard allows this).
Impressive, i had no idea about this!
So what you have to do is the reverse of when you put the data in. I.e.:
memcpy(i, a+member_offset[0], member_size[0]);
printf("Integer is: %d\n", i);
Ideally you should add at least basic error trapping, i.e.
if (member_size[0] != sizeof i)
fputs("ERROR: Size miss-match!\n");
else {
memcpy(i, a+member_offset[0], member_size[0]);
printf("Integer is: %d\n", i);
}


All is perfectly clear now, but why the error checking since i should have
explicitly set member_size[0] to sizeof(i) earlier in the program anyway?
Feb 9 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2171
by: Gleep | last post by:
Hi PHP coders, I've got an issue I'm stuck with. Imagine there is a large form that has 5 columns and 20 rows. In each row there is a check box - then 4 input fields. I already have the code that inserts all the data BUT the validation is a nightmare. What I need is. If an entire row is empty (not checked or filled out) that's OK. However if a user fills in one or two input fields within a row - that's NOT ok. The entire row needs...
1
19175
by: Stephan | last post by:
Hi, I'm using Visual Studio 2003 (C#) with the integrated Crystal Report software and have the following question: How can I assign a value (string) to an unbound (string) field in Crystal Report at runtime? Example: private void button1_Click(object sender,
16
12033
by: Raj Kotaru | last post by:
Hello all, I recently came across the following segment of code that defines a C struct: typedef struct { unsigned char unused_bits:4; unsigned char wchair_state:2; } xyz;
5
38369
by: mblatch | last post by:
Another basic C# question, but haven't figured out how to do this one either. Am used to defining a list of structures in C++, but am unsure if you can do this in C#. As a simplified example, I have: struct Command { int commandEnum; string commandName; int commandLength; byte command;
3
5174
by: Obrecht | last post by:
Hi. I am new to VB .NET and am just starting to do some testing with it. I am trying to define a fixed length array of structures within a structure. I pass this structure to a Win32 Btrieve API. I have one main structure and within that I need to have a fixed length array of 200 other structures. Below - shortened versions of the structures.
6
3423
by: Charles Law | last post by:
I have the following structure (for example) that I wish to convert for use in VB.NET. What would be the best way to do it? Ideally, it would convert directly to allow access to the bit fields in the same way as in C++, but I cannot see any mention of bit field declarations in VB.NET. <structure> typedef struct _DCB { DWORD DCBlength; DWORD BaudRate; DWORD fBinary :1;
6
1817
by: Duderino82 | last post by:
I was wondering if there is a way to collect the names of the fields from a specific table. I think the soluction is to be researched in the sql code but maybe someone knows of a way to o so directly from php. Example. Table: Categories Field1: type1 Field2: type2 Field3: type3 Field4: type4
9
5710
by: sean.scanlon | last post by:
can someone help understand how i can could access a struct field dymanically like: foo->fields ? when i try to compile this i get the following error: 'struct pwd' has no member named 'fields' is there a way to treat fields as the member name of the struct?
2
1917
by: Cliff Martin | last post by:
I want to define several groups of related magic numbers. I am writing a program to parse someone else's formatted data, and they have several fields that could be set to a number of different values. Rather than hardcode a number I want to use a text to make it clear what I am comparing to. examples: FieldA 1 foo 2 bar
2
5951
by: DiAvOl | last post by:
Hello everyone, I read here and there that bit-field usage should be avoided because it's not portable. My question is why it's not portable? For example let's say I have a struct in my code with bit-fields like the following: struct bitfield_t { unsigned int val1 : 1; unsigned int val2 : 3;
0
9198
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
7973
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6646
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5967
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4477
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4738
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3175
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2541
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2119
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.