|
-
Jan 24th, 2003, 02:28 PM
#1
Thread Starter
Lively Member
Different structures in one array, how?
I've 7 structures. Smallest structure has 2 variables and largest 8.
struct invA_typ { // smallest struct
long A;
long B;
}
struct invG_typ { // largest struct
long A;
...
long G;
}
I've to deal with all the structs as one array to loop trough them, how can I do that?
Thanks in advance
-
Jan 24th, 2003, 04:43 PM
#2
Frenzied Member
You can nest structs
Code:
typedef struct{
struct{
long x;
long y;
}a;
struct{
long x;
long y;
long z;
}b;
} myrecord;
struct myrecord recs[200];
for (int i=0;i<200li++){
recs[i].a.x=0;
recs[i].a.y=0;
recs[i].b.x=0;
recs[i].b.y=0;
recs[i].b.z=0;
} // how to reference the elements
-
Jan 24th, 2003, 04:52 PM
#3
Thread Starter
Lively Member
I guess that will take a lot of memory. I can just stick to the largest struct but still thats too much memory.
anyways thanks for the reply
Last edited by XfoxX; Jan 24th, 2003 at 04:57 PM.
-
Jan 25th, 2003, 02:59 AM
#4
Fanatic Member
I think you should use an array of pointers for this. All elements in this array should hold a pointer to one of your structures. Memory management will be harder this way, but it's the way I think it costs the least memory.
Jim: I think an union is better than a structure of structures. An union will be as large as the largest element it holds, in this case structure g.
Code:
typedef union{
struct{
long x;
long y;
}a;
struct{
long x;
long y;
long z;
}b;
} myrecord;
But, as XfoxX said, this costs apparently too much memory.
-
Jan 25th, 2003, 03:04 AM
#5
Fanatic Member
Hmm, XfoxX, I was thinking of another approach to your problem. Since you're always using the same datatype, and since that data type is integral, you can place everything in one single array. Just forget about the structures. How? The first element in the array will indicate the size of the former structure, which is i. The next i elements will hold the data of the various elements of the structure. Then the following element has the size of the next structure, j. The next j elements have the data. Etcetera.
An example:
0: 3 (which is the size of structure B)
1: first element of structure B
2: second element of structure B
3: third element of structure B
4: 6 (structure G)
5: first element of G
6: second element of G
10: sixth element of G
11: 2 (structure A)
12: first element yadda yadda
A disadvantage is that you cannot see the total number of structures at a glance. You have to go through the array, but this should be fast enough.
-
Jan 25th, 2003, 09:51 AM
#6
All of those are half-hearted solutions that impose more work on the programmer. And they are prone to bugs.
You should rethink your design. Why do you have to have 7 different structs in one array?
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 25th, 2003, 10:11 AM
#7
Thread Starter
Lively Member
Cornedbee, because fields in each type of record varies. I would loop from each type of record seprately, but I need to make the looping process shorter and faster. riis you have a good idea, although it might make difficult to trace errors, but it's fast and takes less memory. Unfortunately fields have different data type. I guess keeping an array of pointers might be the best approach.
-
Jan 25th, 2003, 10:18 AM
#8
Monday Morning Lunatic
You could have a slightly simpler version of polymorphism here:
Code:
struct proxy {
int type;
void *obj;
};
struct big {
int A, B, C, D, E, F, G;
};
struct small {
int A, B, C;
};
enum types { t_big, t_small };
const size_t SIZE = 50;
proxy records[SIZE];
for(size_t i = 0; i < SIZE; ++i) {
if(i % 2) {
records[i].type = t_big;
records[i].obj = (void*)new big;
} else {
records[i].type = t_small;
records[i].obj = (void*)new small;
}
}
...then you can read them as necessary. I wouldn't really recommend that though. It may be partially more efficient, but all that casting to void*...ugh. Far simple to use polymorphism:
Code:
struct small {
int A, B, C;
};
struct big : public small {
int D, E, F, G;
};
const size_t SIZE = 50;
small* records[SIZE];
for(size_t i = 0; i < SIZE; ++i) {
if(i % 2) {
records[i].obj = new big;
} else {
records[i].obj = new small;
}
}
I think. I haven't compiled that so...
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Jan 25th, 2003, 10:30 AM
#9
Yeah, but that only works in C++.
Hmm....
Actually I think that having seperate arrays for each data type would be the fastest and most memory efficient. Every way of stuffing them all into one array wastes memory in some way and the identification takes time.
The only thing that would increase would be code size, and that is usually the least critical factor (except in bootstraps )
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 25th, 2003, 10:31 AM
#10
And for polymorphism you need RTTI enabled to find out what this really is.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 25th, 2003, 10:33 AM
#11
If you can't avoid it I would recommend a "variable node linked list". A linked list that has different node types.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 25th, 2003, 10:37 AM
#12
Monday Morning Lunatic
My first option will work (with a couple of changes) in C.
As for multiple arrays, yeah, that would be a fair bit quicker.
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Jan 25th, 2003, 01:52 PM
#13
Fanatic Member
Multiple arrays will only be a good idea if you're sure the order of all records doesn't matter. Else a linked list, as CornedBee suggested, might be better. But, in that case, you have to go through all the list if you want to extract the data of the last record.
-
Jan 25th, 2003, 02:23 PM
#14
Monday Morning Lunatic
Make it pinned at both ends, and doubly-linked. That way you only have to go 1/2 way at maximum. That is, if you know more-or-less where it is.
However, regarding the multiple arrays idea...you could always have another array, that holds the indexes in the two other arrays. However, for one of the arrays, there is a high bit set, that you can test for and mask off. This will limit you to half the range of the value you store in the "root" array, so I'm skeptical, but it should work unless you have more than about 2 milliard items.
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Jan 25th, 2003, 07:07 PM
#15
But he has 7 structures, not just 2. Those were just examples.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 26th, 2003, 02:43 AM
#16
Fanatic Member
So, what's wrong with the array of pointers concept I mentioned? (Aside from the memory management aspects.)
-
Jan 26th, 2003, 05:29 AM
#17
Nothing. But the memory management and the ID of the structs are not fun.
You approach is good. I just don't think it's the best, but that depends on the exact situation.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 26th, 2003, 05:36 AM
#18
Monday Morning Lunatic
A "best" solution is frequently unattainable, in practice.
In this situation it might be productive to look at *why* we're trying to do this. No point solving the wrong problem, if there's a better solution to a different problem, solving the original problem as a by-product
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Jan 26th, 2003, 07:07 AM
#19
Very true. That's what my first post was about.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 26th, 2003, 07:20 AM
#20
Monday Morning Lunatic
Oh yeah. Forgotten about that one
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Jan 26th, 2003, 10:03 AM
#21
Frenzied Member
Use a masthead-like array. Read and write the record essentially blindly.
Let the array remember what kind of record it has in it.
Code:
struct recptr{ // masthead
short type;
void *p;
}
struct r1{
long a;
char b[20];
}
struct r2{
char a;
double b;
char c;
}
struct r3{
char a[40];
float b;
short c;
}
// and so on to r7
int rsizes[8];
struct recptr lst[200];
int currecptr=(-1);
.............
rsizes[1]=sizeof(struct r1);
rsizes[2]=sizeof(struct r2);
.........
rsizes[7]=sizeof(struct r7);
void add_array_element(short type){
currecptr++; // allocate a record of the type you need
lst[currecptr].type=type;
lst[currecptr].p =(void*) calloc(1,rsizes[type]+1);
}
void readrecord(int rectoread, FILE *instream){
// read it from file
fread(lst[rectoread].p,rsizes[lst[rectoread].type],1,instream);
}
void write record((int rectowrite, FILE *ostream){
// write it to file
fread(lst[rectowrite].p,rsizes[lst[rectowrite].type],1,ostream);
}
-
Jan 26th, 2003, 10:10 AM
#22
Frenzied Member
PS:
The 'too-much-memory' argument is nice, but unless you're working in 16 bit environments, it usually is not valid. Memory mAngement in 32-bit environments lets you read/write VERY large
(100MB files) on boxes with less memory than the file size. I
Plus, the compiler aligns members of a struct - packs them with filler to word-align integral members - which uses up more memory.
We have to read stuff written by DOS boxes (hand held meter uploads) on a unix box. We have to outsmart the unix compiler
by doing something like the above, except we don't use
Code:
rsize[3]=sizeof(struct whatever);
because the structs may or may not have padding, whereas the stuff that the DOS box creates are not packed. We cast each segment to a known data type using a map that gives the sequences and kinds of datatypes.
-
Jan 26th, 2003, 04:26 PM
#23
The 'too-much-memory' argument is nice, but unless you're working in 16 bit environments, it usually is not valid. Memory mAngement in 32-bit environments lets you read/write VERY large
(100MB files) on boxes with less memory than the file size.
That you have a lot of memory is no reason not to save as much as you reasonably can.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 26th, 2003, 04:27 PM
#24
BTW, doesn't gcc have an option to tell it not to pack structs?
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 26th, 2003, 04:33 PM
#25
Monday Morning Lunatic
-fno-pack-structs or something like that.
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Jan 28th, 2003, 07:49 AM
#26
Thread Starter
Lively Member
thanks for the input
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|