473,386 Members | 1,741 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Need a GURU! I'm stuck....


I don't know the easiest way to explain this so, I'm going to give an
example of how it is today....and what I'm trying to accomplish.

in the header...
typedef struct XXX_ELEMENT_tag
{
UINT8 num;
UINT8 param;
UINT16 fre1;
INT16 a1;
} ;
typedef struct XXX_ELEMENT_tag ELEMENT_T;

#define MAX_ELEMENTS 8
typedef struct XYZ_S_tag {
UINT8 num_elements;
UINT8 flag;
ELEMENT_T element[MAX_E]; /*** This is the spot ***/
} XYZ_S_tag;

And of course the S_tag structure is buried one more structure down. Say
something like:

typedef struct T_TABLE_tag
{
XYZ_S_tag run;
XYZ_S_tag walk;
.... /* alot of these */
XYZ_S_tag crawl;
} TABLE_T;
typedef struct T_TABLE_tag T_table;

And in a C file a global is initialized like this...
T_table t_table =
{
{ /* run */
2, /* Num Elements */
APPLY_WINDOW, /* Flag */
{
/* N p f a */
/* 0 */ { 2, 0, 480, -240 },
/* 1 */ { 0, 0, 0, 500 },
/* 2 */ { 0, 0, 0, 0 },
/* 3 */ { 0, 0, 0, 0 },
/* 4 */ { 0, 0, 0, 0 },
/* 5 */ { 0, 0, 0, 0 },
/* 6 */ { 0, 0, 0, 0 },
/* 7 */ { 0, 0, 0, 0 },
/* 8 */ { 0, 0, 0, 0 },
}
},
{ /* walk */
/* repeat many many times */

}
}

Ok, let's just say element is bigger than my example above and there are
about a 1000 of these, only half of which have data. I've inherited
this code and this table is occupying 300k of memory and memory's tight.
I want to delete all the filler rows and declare element in a way that
the compiler will auto size what it needs for each instance. I have the
number of elements. I would have thought something along the lines of
*element instead of element[MAX_E]. But I get warnings about the
unexpected brace for element. Is there a way to make the compiler(gcc)
auto size the space for me? In the above example I would be deleting
rows 2-8.

Any and all help is appreciated?

Thanks
cj
Jan 17 '08 #1
8 1620

when I did the *element, tons of warnings and then errors out saying to
many items for element. I also tried element[] and it didn't like that
at all. The header file errors during compile with incomplete
declaration error. Sorry I don't have it in front of me...

Again, any thoughts or ideas would be appreciated.

Chris LaVelle wrote:
>
I don't know the easiest way to explain this so, I'm going to give an
example of how it is today....and what I'm trying to accomplish.

in the header...
typedef struct XXX_ELEMENT_tag
{
UINT8 num;
UINT8 param;
UINT16 fre1;
INT16 a1;
} ;
typedef struct XXX_ELEMENT_tag ELEMENT_T;

#define MAX_ELEMENTS 8
typedef struct XYZ_S_tag {
UINT8 num_elements;
UINT8 flag;
ELEMENT_T element[MAX_E]; /*** This is the spot ***/
} XYZ_S_tag;

And of course the S_tag structure is buried one more structure down. Say
something like:

typedef struct T_TABLE_tag
{
XYZ_S_tag run;
XYZ_S_tag walk;
.... /* alot of these */
XYZ_S_tag crawl;
} TABLE_T;
typedef struct T_TABLE_tag T_table;

And in a C file a global is initialized like this...
T_table t_table =
{
{ /* run */
2, /* Num Elements */
APPLY_WINDOW, /* Flag */
{
/* N p f a */
/* 0 */ { 2, 0, 480, -240 },
/* 1 */ { 0, 0, 0, 500 },
/* 2 */ { 0, 0, 0, 0 },
/* 3 */ { 0, 0, 0, 0 },
/* 4 */ { 0, 0, 0, 0 },
/* 5 */ { 0, 0, 0, 0 },
/* 6 */ { 0, 0, 0, 0 },
/* 7 */ { 0, 0, 0, 0 },
/* 8 */ { 0, 0, 0, 0 },
}
},
{ /* walk */
/* repeat many many times */

}
}

Ok, let's just say element is bigger than my example above and there are
about a 1000 of these, only half of which have data. I've inherited
this code and this table is occupying 300k of memory and memory's tight.
I want to delete all the filler rows and declare element in a way that
the compiler will auto size what it needs for each instance. I have the
number of elements. I would have thought something along the lines of
*element instead of element[MAX_E]. But I get warnings about the
unexpected brace for element. Is there a way to make the compiler(gcc)
auto size the space for me? In the above example I would be deleting
rows 2-8.

Any and all help is appreciated?

Thanks
cj
Jan 17 '08 #2
Chris LaVelle said:
>
I don't know the easiest way to explain this so, I'm going to give an
example of how it is today....and what I'm trying to accomplish.
[Chris LV is trying to get himself a ragged array, but he wants to
initialise it using ordinary array initialisation syntax.]

Alas, no, you can't do this in the way you would like to do it.

You *can*, however, get the behaviour you desire. The easiest way to do it
is probably via a runtime file containing the data, one item per line. If
this can contain an item count at the start of each line, so much the
better. If it can contain a line count at the very start of the file,
that's better still. (But if either or both of those hints-to-the-program
aren't possible, there's a workaround called realloc.)

Define your variable-length data as... well, I was about to suggest that
you use ELEMENT_T *element, but I can't do that with a clear conscience
because the ELEMENT_T identifier is reserved for the implementation! But
whatever type name you end up using, element needs to be a pointer to that
type.

Having decided how many items you want, you do this in your read-loop:

/* we need n items on this line */
t_table.run[i].element = malloc(n * sizeof *t_table.run[i].element);
if(t_table.run[i].element != NULL)
{
read n lots of num, param, fre1, and a1 from the file and store
them in t_table.run[i].element[0] through t_table.run[i].element[n-1]
}
Disadvantage of this technique: the successful running of your program now
requires the existence of this external file.

Advantages: it gives you the memory saving you require; and it allows you
to change the initialisation values without recompiling the code (okay,
whether this is an advantage is a matter of opinion).

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jan 17 '08 #3
Chris LaVelle <cjlave...@yahoo.comwrote:
...
typedef struct XXX_ELEMENT_tag
{
* *UINT8 * num;
* *UINT8 * param;
* *UINT16 *fre1;
* *INT16 * a1;} ;

typedef struct XXX_ELEMENT_tag ELEMENT_T;

#define MAX_ELEMENTS 8
typedef struct XYZ_S_tag {
* * UINT8 * * num_elements;
* * UINT8 * * flag;
* * ELEMENT_T element[MAX_E]; * */*** This is the spot ***/

} XYZ_S_tag;

And of course the S_tag structure is buried one more
structure down. Say something like:

typedef struct T_TABLE_tag
{
* *XYZ_S_tag run;
* *XYZ_S_tag walk;
* *.... */* alot of these */
* *XYZ_S_tag crawl;} TABLE_T;

typedef struct T_TABLE_tag T_table;

And in a C file a global is initialized like this...
<snip>
>
Ok, let's just say element is bigger than my example
above and there are about a 1000 of these, only half
of which have data. *I've inherited this code and this
table is occupying 300k of memory and memory's tight.
I want to delete all the filler rows and declare
element in a way that the compiler will auto size what
it needs for each instance.*I have the number of
elements. *I would have thought something along the
lines of *element instead of element[MAX_E].
Yes, but that does come at a compromise in that the
pointer takes up space in addition to the array it
points to.
>*But I get warnings about the unexpected brace for
element.
Sounds like a syntactical thing. Take a look at...

#include <stdio.h>

#define countof(x) ( (size_t) (sizeof(x)/sizeof*(x)) )

struct thang
{
const char *name;
size_t count;
const char **element;
};

const char *dwarfs[] =
{
"Bashful",
"Doc",
"Dopey",
"Grumpy",
"Happy",
"Sleepy",
"Sneezy"
};

const char *solids[] =
{
"Tetrahedron",
"Octahedron",
"Cube",
"Icosahedron",
"Dodecahedron"
};

struct thang thangs[] =
{
{ "Seven Dwarfs", countof(dwarfs), dwarfs },
{ "Perfect Solids", countof(solids), solids }
};

int main(void)
{
size_t i, j;

for (i = 0; i < countof(thangs); i++)
{
if (i) puts("");
printf("%s:\n", thangs[i].name);
for (j = 0; j < thangs[i].count; j++)
printf(" %s\n", thangs[i].element[j]);
}

return 0;
}

--
Peter
Jan 17 '08 #4

Firmware, so really no place to stick a file. It has to stay in the
image for now and continue to be a global for madness reasons.

CJ
Richard Heathfield wrote:
Chris LaVelle said:

>>I don't know the easiest way to explain this so, I'm going to give an
example of how it is today....and what I'm trying to accomplish.


[Chris LV is trying to get himself a ragged array, but he wants to
initialise it using ordinary array initialisation syntax.]

Alas, no, you can't do this in the way you would like to do it.

You *can*, however, get the behaviour you desire. The easiest way to do it
is probably via a runtime file containing the data, one item per line. If
this can contain an item count at the start of each line, so much the
better. If it can contain a line count at the very start of the file,
that's better still. (But if either or both of those hints-to-the-program
aren't possible, there's a workaround called realloc.)

Define your variable-length data as... well, I was about to suggest that
you use ELEMENT_T *element, but I can't do that with a clear conscience
because the ELEMENT_T identifier is reserved for the implementation! But
whatever type name you end up using, element needs to be a pointer to that
type.

Having decided how many items you want, you do this in your read-loop:

/* we need n items on this line */
t_table.run[i].element = malloc(n * sizeof *t_table.run[i].element);
if(t_table.run[i].element != NULL)
{
read n lots of num, param, fre1, and a1 from the file and store
them in t_table.run[i].element[0] through t_table.run[i].element[n-1]
}
Disadvantage of this technique: the successful running of your program now
requires the existence of this external file.

Advantages: it gives you the memory saving you require; and it allows you
to change the initialisation values without recompiling the code (okay,
whether this is an advantage is a matter of opinion).
Jan 17 '08 #5

Firmware, so really no place to stick a file. It has to stay in the
image for now and continue to be a global for madness reasons.

But thanks..

CJ
Richard Heathfield wrote:
Chris LaVelle said:

>>I don't know the easiest way to explain this so, I'm going to give an
example of how it is today....and what I'm trying to accomplish.


[Chris LV is trying to get himself a ragged array, but he wants to
initialise it using ordinary array initialisation syntax.]

Alas, no, you can't do this in the way you would like to do it.

You *can*, however, get the behaviour you desire. The easiest way to do it
is probably via a runtime file containing the data, one item per line. If
this can contain an item count at the start of each line, so much the
better. If it can contain a line count at the very start of the file,
that's better still. (But if either or both of those hints-to-the-program
aren't possible, there's a workaround called realloc.)

Define your variable-length data as... well, I was about to suggest that
you use ELEMENT_T *element, but I can't do that with a clear conscience
because the ELEMENT_T identifier is reserved for the implementation! But
whatever type name you end up using, element needs to be a pointer to that
type.

Having decided how many items you want, you do this in your read-loop:

/* we need n items on this line */
t_table.run[i].element = malloc(n * sizeof *t_table.run[i].element);
if(t_table.run[i].element != NULL)
{
read n lots of num, param, fre1, and a1 from the file and store
them in t_table.run[i].element[0] through t_table.run[i].element[n-1]
}
Disadvantage of this technique: the successful running of your program now
requires the existence of this external file.

Advantages: it gives you the memory saving you require; and it allows you
to change the initialisation values without recompiling the code (okay,
whether this is an advantage is a matter of opinion).
Jan 17 '08 #6
On Jan 16, 9:00*pm, Chris LaVelle <cjlave...@yahoo.comwrote:
I don't know the easiest way to explain this so, I'm going to give an
example of how it is today....and what I'm trying to accomplish.

in the header...
typedef struct XXX_ELEMENT_tag
{
* *UINT8 * num;
* *UINT8 * param;
* *UINT16 *fre1;
* *INT16 * a1;} ;

typedef struct XXX_ELEMENT_tag ELEMENT_T;

#define MAX_ELEMENTS 8
typedef struct XYZ_S_tag {
* * UINT8 * * num_elements;
* * UINT8 * * flag;
* * ELEMENT_T element[MAX_E]; * */*** This is the spot ***/

} XYZ_S_tag;

And of course the S_tag structure is buried one more structure down. Say
something like:

typedef struct T_TABLE_tag
{
* *XYZ_S_tag run;
* *XYZ_S_tag walk;
* *.... */* alot of these */
* *XYZ_S_tag crawl;} TABLE_T;

typedef struct T_TABLE_tag T_table;

And in a C file a global is initialized like this...
T_table t_table =
{
* * * * { /* run * * **/
* * * * * * * * 2, /* Num Elements */
* * * * * * * * APPLY_WINDOW, /* Flag */
* * * * * * * * {
* * * * * * * * * * * * /* * * * *N *p * f * * a */
* * * * * * * * * * * * /* 0 */ { 2, 0, 480, -240 },
* * * * * * * * * * * * /* 1 */ { 0, 0, * 0, 500},
* * * * * * * * * * * * /* 2 */ { 0, 0, * 0, 0 },
* * * * * * * * * * * * /* 3 */ { 0, 0, * 0, 0 },
* * * * * * * * * * * * /* 4 */ { 0, 0, * 0, 0 },
* * * * * * * * * * * * /* 5 */ { 0, 0, * 0, 0 },
* * * * * * * * * * * * /* 6 */ { 0, 0, * 0, 0 },
* * * * * * * * * * * * /* 7 */ { 0, 0, * 0, 0 },
* * * * * * * * * * * * /* 8 */ { 0, 0, * 0, 0 },
* * * * * * * * }
* * * * },
* * * * { /* walk **/
* * * * * * * /* repeat many many times */

* * * * }

}

Ok, let's just say element is bigger than my example above and there are
about a 1000 of these, only half of which have data. *I've inherited
this code and this table is occupying 300k of memory and memory's tight.
I want to delete all the filler rows and declare element in a way that
the compiler will auto size what it needs for each instance. *I have the
number of elements. *I would have thought something along the lines of
*element instead of element[MAX_E]. *But I get warnings about the
unexpected brace for element. *Is there a way to make the compiler(gcc)
auto size the space for me? *In the above example I would be deleting
rows 2-8.

Any and all help is appreciated?

Thanks
cj
You have the right idea (one anyway). Replace the mostly ignored
array with a pointer to a correctly sized array.

It sounds like you were trying to intialize a pointer with an
aggregate. Won't work in C. You have to name the array independently
for this to work. You can easily write a perl script to do this
translation. No other code will need changing.

typedef struct XYZ_S_tag {
UINT8 num_elements;
UINT8 flag;
ELEMENT_T *element; /*** Changed to pointer ***/
} XYZ_S_tag;

typedef struct T_TABLE_tag
{
XYZ_S_tag run;
XYZ_S_tag walk;
.... /* alot of these */
XYZ_S_tag crawl;
} TABLE_T;

typedef struct T_TABLE_tag T_table;

ELEMENT_T run_elements[] = {
/* 0 */ { 2, 0, 480, -240 },
/* 1 */ { 0, 0, 0, 500 } };

T_table t_table =
{
{ /* run */
2, /* Num Elements */
APPLY_WINDOW, /* Flag */
run_elements
},
{ /* walk */
/* repeat many many times */

}
}

Another approach is to declare a different record type for each
possible number of elements. If your max is really only 8, this is
reasonable. Preprocessor abuse will help:

#define DECLARE_XYZ(Size) \
typedef struct XYZ_S_ ## Size ## _tag { \
UINT8 num_elements; \
UINT8 flag; \
ELEMENT_T element[Size]; \
} XYZ_S_ ## Size ## _tag

DECLARE_XYZ(1); DECLARE_XYZ(2); DECLARE_XYZ(3);DECLARE_XYZ(4);
DECLARE_XYZ(5); DECLARE_XYZ(6); DECLARE_XYZ(7);DECLARE_XYZ(8);

Now,

typedef struct T_TABLE_tag
{
XYZ_S_2_tag run;
XYZ_S_4_tag walk;
.... /* alot of these */
XYZ_S_1_tag crawl;
} TABLE_T;

T_table t_table =
{
{ /* run */
2, /* Num Elements */
APPLY_WINDOW, /* Flag */
{
/* N p f a */
/* 0 */ { 2, 0, 480, -240 },
/* 1 */ { 0, 0, 0, 500 },
}
},
{ /* walk */
4,
FLAG,
{
/* N p f a */
/* 0 */ { 2, 0, 480, -240 },
/* 1 */ { 0, 0, 0, 500 },
/* 2 */ { 2, 0, 480, -240 },
/* 3 */ { 0, 0, 0, 500 },
}
/* repeat many many times */
}
}

Again a little script will fix you right up...
Jan 17 '08 #7
Richard Heathfield <r...@see.sig.invalidwrote:
...I was about to suggest that you use ELEMENT_T *element,
but I can't do that with a clear conscience because the
ELEMENT_T identifier is reserved for the implementation!
Strictly speaking, it's reserved for use as a macro if
<errno.his included. But since someone might one day
want to include that header, that's normally enough
reason to steer clear of EXXXX identifiers.

--
Peter
Jan 17 '08 #8
[Please don't top post; responses should go under the relevant quoted
text, and non-relevant quoted text should be removed.]
>Richard Heathfield wrote:
>[Chris LV is trying to get himself a ragged array, but he wants to
initialise it using ordinary array initialisation syntax.]

Alas, no, you can't do this in the way you would like to do it.

You *can*, however, get the behaviour you desire. The easiest way to do it
is probably via a runtime file containing the data, one item per line. If
this can contain an item count at the start of each line, so much the
better. If it can contain a line count at the very start of the file,
that's better still. (But if either or both of those hints-to-the-program
aren't possible, there's a workaround called realloc.)
[And mallocate memory and read the data from a file at run time,
allocating only the amount of memory that's actually needed]
In article <_d******************************@comcast.com>,
CJ LaVelle <cj*******@yahoo.comwrote:
>
Firmware, so really no place to stick a file. It has to stay in the
image for now and continue to be a global for madness reasons.
You can write code that is set up as a ragged array that's entirely in
the image, and end up with something not entirely unlike this:
(We've lost your original data structure definitions, so I'll use
minimal ones for the purposes of illustration)
--------
struct element
{
/*Stuff that goes in each element*/
};

struct row
{
/*Number of elements in this row*/
int nelems;
struct element *elems;
};

/*The actual data, compacted into a single one-dimensional array*/
struct element *all_elems[]=
{
/*The next seventeen elements are for row 0*/
{ /*initializer for first element in row 0*/ },
/*...sixteen more initializers for row 0...*/

/*The next three elements are for row 1*/
{ /*initializer for first element in row 1*/ },
{ /*initializer for second element in row 1*/ },
{ /*initializer for third element in row 1*/ },

/*The next 42 elements are for row 2*/
{ /*initializer for first element in row 2*/ },
/*...41 more initializers for row 2...*/

/*Initializers for the rest of the rows*/
};

/*We access the data through this array of struct row*/
struct row *rows[]=
{
/*Row 0: 17 elements*/
{17, &all_elems[0]},
/*Row 1: 3 elements*/
{3, &all_elems[17]},
/*Row 2: 42 elements*/
{42, &all_elems[20]},

/*...and for the rest of the rows...*/
};
--------
This will obviously be incredibly tedious and fragile to maintain by
hand; every time something gets added in the middle, every row after
that has to have its initializers updated, and forgetting something or
getting an addition wrong will give you a bug that's likely to be hard
to trace.

It should, however, not be too hard to write a program that reads a
file in the format that Richard H described and writes this code for
you - computers are, after all, extremely good at things that are
tedious and purely mechanical to do by hand. Then all you have to do
is run the code generator as part of your build process, and you get a
nice compact (and statically initialized, which may be important for a
firmware application) internal representation in your image AND an
easy-to-edit input format for your development.
dave

--
Dave Vandervies dj3vande at eskimo dot com
It might actually be true for these groups that "C is a dead language".
At least at the levels they work at, generating AJAX to provide many new
security vulnerabilities. --Jack Klein in comp.lang.c
Jan 17 '08 #9

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

Similar topics

11
by: Mike Cox | last post by:
After writing an article trashing java, and C++, notable LISP guru Paul Graham is getting roasted on slashdot. Apart from AutoCAD and Emacs, what has LISP done anyway? Most real work is done in...
2
by: rmn | last post by:
Hi, I'm looking for the translation betwen the color spaces, but I must be mistaken with the methods to use, losing the values. Please, I need a little help of a "coloured guru"....
4
by: Accolo1 | last post by:
Help we are looking for this person, do you know them? William wjohnson@accolo.com Title: BEA WebLogic Portal Guru Job #: 03-04468 Check the pulse of your career! Evolve our eCommerce web...
1
by: Jarrod Hyder | last post by:
Ok, I wrote my own weblog and I'm working on the web interface for adding/editing my posts. I decided to add a little preview button...when the button is clicked it is suppose to open a pop-up...
5
by: trint | last post by:
The WritePrinter() is working. I know this ReadPrinter() implementation isn't correct because it never reads into "reaDstrinG" buffer from the printer...But, I'm sure one of you Guru's do know how...
4
by: Tim::.. | last post by:
I have asked this question several times and can't seem to get the answer I am looking for! I am trying to create a form that responds dynamically to the users choises within the page. At the...
16
by: Singulus | last post by:
Hello all, I've searched for similar threads, I've found some bit of useful info here and there, but nevertheless I want to post my questions...So, how can I (we, in fact the forum can benefit...
6
by: Steven W. Orr | last post by:
Given the following code: (I hope it's as simple as possible) :-) #! /usr/bin/python import new class BASE: def __init__( self ): print 'Hello from BASE init' def m1( self ): print 'M1 Base:...
2
by: Dotan Cohen | last post by:
I need an application, and I'd like it to be written in Python with QT as I am a KDE user. I simply don't have the time to code it myself, as I've been trying to find the time for half a year now....
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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...

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.