Re: vasam
Barry,
You are so funny, you start off calm, cool and collective and by the end of
the posts you loose it!
STOP CODING. START THINKING.
Pretty hard to think when someone is always throwing gasoline on the fire!
The program needs to send data to another component of the
system. The data consists of multiple (do you know how many?)
sequences of numeric values. Different sequences contain different
quantities of these values.
For each sequence, we know how many values it should contain
and ... We need to generate ...
When all the sequences have been generated, ...
Other random thoughts (which should be saved until after you achieve
the above):
Where are all the data values coming from? Must they be computed on
the fly or can you build a set of initialization values?
Look at how much processing is repeated for each record. Doesn't this
suggest something to you?
Really! You really think the above is crystal clear. Hmmmm! In my humble
opinion, when you hear of people coding in the language for 30 years, it
makes me a beginner chump! And the best feedback which evaluates your methods
of giving advice and aid comes from a beginner. So as constructive chritisism
(not that I am saying that your above description doesn't make sence) but
please, don't ever write a book on any programming language... cause you will
confuse the hell out of everyone.
Enough said about your character!
You are in love with nested structures. It's killing you. Stop it.
I was trying stuff... in the hopes of getting advice, stop being difficult!
Why do you need an lb whose only purpose is to point to an lb_table?
Because there could be multiple lb's pointing to different tables. You seem
to assume that the code samples I present are done exactly this way in my
project. The samples are very watered down snippets which really don't
represent the whole picture. And you don't need the whole picture, because it
would be too long!
Why do you need a listx whose only purpose is to point to some longs?
This has been corrected!
What percentage of your lb_table will be short? Is it worth hard
coding a long[5] if most will need an additional allocation?
Hey! you don't listen ! Instead of flying off on a tantrum read my post(s)
before complaining. I did say the following didn't I:
"But the idea here is to fill out the table "lb_table" for 5 items and when
the odd time comes where I need more than 5 items, I select a storage array
space to accomodate eeprom data for 6 to 10 items, 11 to 30 items or 31 to 60
items as required for that specific record. "
To the rest of this forum, I am sorry if I rushed on the samples, and in the
furture I will try to be more concise and keep their size down.
Scot T, thanks for your input, and I would get back to you with a better
sample, but it seems it got quite complicated for nothing (I appolagize) ...
and I think I complicated it becuase I wasn't sure exactly what I wanted. But
I did figure out a way to do what I need thanks to Barry's code proposition.
It was very simple. Here is the code which with some modifiations will fit
into my global project's coding approach.
Barry, all I was looking for is the sample code below:
(And don't start nitpicking at it, because certain lines will be relocated
to specific sections of my project which will make sence with the rest of the
code. I guess you won't like the innitializations directly on the table, but
then again there are lots of things you don't like about me or my code....
too many uneccessary things !)
Nontheless, you did inspire me to come up with a solution, so I guess your
roughing me up methods actually were good for me and besides you did teach me
stuff in your code proposition below:
==========================================
listx x[] = {
{malloc(5 * sizeof(long))},
.... as many as you want
{malloc(5 * sizeof(long))}
};
When it comes time to use more
long *temp;
temp = x[i].storage;
x[i].storage = realloc(temp, 10 * sizeof *x[i].storage);
========================================
because I had never used malloc this way and I never used realloc before. So
under these circumstances
thanks for your help.
==========================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SHORT 0
#define LONG 1
typedef struct tag_lb_table
{
long lb_items[5];
short list_type;
long *x;
}lb_table;
typedef struct tag_lb
{
struct tag_lb_table *dc;
//...other members here
}lb;
// Other parameters passed in this function are not shown!
lb* create_obj(lb *ptr_lb, lb_table *dc)
{
ptr_lb = malloc (sizeof *ptr_lb);
ptr_lb->dc = dc;
//...Other setups here not shown
return ptr_lb;
}
void store_to_eeprom(lb *objLb)
{// funtion which stores all storage
// informations from from every record to eeprom
}
int main()
{
lb MyRef3;
lb *objLb1 = &MyRef3;
lb_table lb_arr[] = {
{ 185, 184, 183, 0, 0, SHORT, 0}, // 3 default values
{ 0, 0, 0, 0, 0, LONG, {malloc(1 * sizeof(long))},}, //<<< long
list,
{ 0, 0, 0, 0, 0, LONG, {malloc(1 * sizeof(long))},}, //<<< long
list
{ 85, 4, 204, 11, 28, SHORT, 0,}, // 5 efault values
// ...
};
objLb1 = create_obj(objLb1, lb_arr);
// Set the size for long lists in records #2 and #3 only!
objLb1->dc[1].x = realloc(objLb1->dc[1].x , 10 * sizeof(long));
objLb1->dc[2].x = realloc(objLb1->dc[2].x , 30 * sizeof(long));
// For record #1 (alter 3 items)
if(objLb1->dc[0].list_type){// Its not a long list!
}
else
{
objLb1->dc[0].lb_items[0] = 188;
objLb1->dc[0].lb_items[1] = 180;
objLb1->dc[0].lb_items[2] = 189;
}
// For record #2 (alter 10 items in dynamic memory???)
if(objLb1->dc[1].list_type){
objLb1->dc[1].x[0] = 100;
objLb1->dc[1].x[1] = 101;
objLb1->dc[1].x[2] = 102;
//..
objLb1->dc[1].x[9] = 109;
}
else {// Its not a short list!
}
// For record #3 (alter 30 items in dynamic memory???)
if(objLb1->dc[1].list_type){
objLb1->dc[2].x[0] = 200;
objLb1->dc[2].x[1] = 201;
objLb1->dc[2].x[2] = 202;
//...
objLb1->dc[2].x[29] = 229;
}
else {// Its not a short list!
}
// For record #4 (store 5 items directly in record #4)
if(objLb1->dc[2].list_type){// Its not a long list
}
else
{
objLb1->dc[3].lb_items[0] = 188;
objLb1->dc[3].lb_items[1] = 180;
objLb1->dc[3].lb_items[2] = 189;
objLb1->dc[3].lb_items[3] = 188;
objLb1->dc[3].lb_items[4] = 180;
}
// Once user is finished with object, all informations
// in table and in dynamic allocations get stored to eeprom
store_to_eeprom(objLb1);
free(objLb1);
return 0;
}
=====================================================
I thank everyone for their help.
--
Best regards
Roberto
"Barry Schwarz" wrote:
On Mon, 20 Jul 2009 21:18:01 -0700, Robby
<Robby@discussions.microsoft.com> wrote:
Hello,
Here is the sequel of my previous post "Variable array sizes as members"
I was given some advice on how to use malloc and realloc in oder to achieve
extra storage for certain records of a table. My sample is slightly different
from the previous post.
I have tried to test various ways but don't seem to know how to make it fit.
I am really stuck and hope someone can help.
I have a table called lb_arr and in this table I have an item called
Let's try for some consistent terminology. Is the table a structure?
Do you have an array of these structures or is lb_arr a single
structure?
list_type which depicts if the amount of data to be stored is > 5. Therefore
if list_type is False then we store data (<=5 items) in the lb_items[5] array
I take it you mean <=5 values.
which is a member of the tag_lb_table. If the list_type is true, then we must
Is tag_lb_table a type or an object?
allocate some memory dynamically to store a certain amount of longs. The
If lb_items is an array then you cannot reallocate it to occupy more
space. Do you intend to have the first 5 values in lb_items and the
remaining values in the allocated space?
difference between this post and my last post is that in the last post I
showed that data was stored to eeprom between every record. Which is false,
What does this have to do with the preceding discussion? What you do
with the data and how frequently you do it is at best only
tangentially related to the data organization.
what I really need is to store the data to eeprom once all the records are
proccessed. Therefore it means that all the records which have data in
lb_items[] array and the ones that required extra dynamic memory must be kept
until the end of the object's life.
What object?
Let me go through it one step at a time. Record #1 has:
What record? Are you talking about data you input or is this the
first element of lb_arr?
{ 185, 184, 183, 0, 0, SHORT, 0},
Which says that I will be storing 3 items and that it is a short list (<=5
items)
Therfore somewhere in my object's logic 185, 184 and 183 might be altered
Object's don't have logic. If they are aggregates, the do have
organization.
becuase of certain conditions. I showed this in my sample code below as a
simple
if/else statement... see it at "For record#1" comment in the sample code
below. Record #1 has no problems for keeping the 3 items because its in the
table within the lb_items[5] array.
However, when we get to record#2, now we need to store 10 items, so our
table at record #2 only has dedicated spots for only 5 items in the lb_items
array, right!. Therefore I would like to store dynamically values 100 to 109
using malloc. I tried a few ways to do this but I get errors. I will mention
the errors later on.
If we look at record#3, we have the same problem except now its for for 30
items. But you see, realloc might not be the sollution because I want to keep
the dynamic data from record #2. So if we realloc what was malloced for
record #2 we will loose the values that were stored (100 to 109).
If we look at record #4, here again, there is no problem because we have <=5
items and can gracefully sit in the table at the lb_items[] array.
When I finish going through all my records, I finally save all the data into
eeprom. This means I go through one record at a time and if the list is
short, I go get the 5 items in the lb_items[]array corresponding to the
current record. If the list is long I go and get all the values in the
dynamic memory and store them into eeprom and so on....
My only problem is, how do I store the items using malloc. Barry gave me a
good solution, but I tried implementing it and I get errors and don't quite
understand how I should do this. Can someone give me a basic sample or a hint
on what I am doing wrong in the code below, I get the following error:
1>c:\_dts_programming\c_programming\c\c_tests\c_string_samples\misc_c_samples\varraysasmembers3.c(58)
: warning C4047: 'initializing' : 'long' differs in levels of indirection
from 'long *'
See where error points in code sample below!
Also I will have to free every malloc done in list x. Never freed malloc
like this. I gather it would be somewhere along the lines of:
================
for(i=0; i< 2; i++)
free(x[i]);
================
Here is the code, I hope someone can help!
=====================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SHORT 0
#define LONG 1
typedef struct t_listx
{
long *storage;
}listx;
What is the point of a structure with only one member? Get rid of it
completely.
typedef struct tag_lb_table
{
long lb_items[5];
Change lb_items to a single long*.
short list_type;
//struct t_listx *x;
long x;
Surely you meant for this to be long *x. Since you have commented out
the previous line, listx is even more useless.
}lb_table;
typedef struct tag_lb
{
struct tag_lb_table *dc;
//...other members here
}lb;
Is there some reason these other members cannot be in lb_table so you
can get rid of one level of indirection?
// Other parameters passed in this function are not shown!
lb* create_obj(lb *ptr_lb, lb_table *dc)
{
ptr_lb = malloc (sizeof *ptr_lb);
You are still passing in values you throw away.
ptr_lb->dc = dc;
//...Other setups here not shown
return ptr_lb;
}
void store_to_eeprom(lb *objLb)
{
// funtion which stores all storage
// informations from from every record to eeprom
}
int main()
{
long a, b;
lb MyRef3;
lb *objLb1 = &MyRef3;
Why not use NULL here and get rid of MyRef3? (Mandatory if you use
realloc as described below.)
listx x[] =
{
{malloc(5 * sizeof(long))},
{malloc(5 * sizeof(long))}
//...
};
Since lb_table no longer has a pointers to listx, x might as well be
an array of long* and save yourself a mess of typing.
long *x[] = { ...};
lb_table lb_arr[] = {
{ 185, 184, 183, 0, 0,SHORT, 0},
{ 0, 0, 0, 0, 0, LONG, x[0].storage}, //<<< error ! store my
data here?
This is due to the typo in the typedef of lb_table noted above.
{ 185, 200, 43, 22, 150,LONG, x[1].storage,}, //<<< error ! store my data
here?
{ 85, 4, 204, 11, 28,SHORT, 0,},
// ...
};
objLb1 = create_obj(objLb1, lb_arr);
// For record #1 (store 3 items directly in record #1)
if(objLb1->dc[0].list_type)
What purpose does objLb1 serve? This code is equivalent to
if (lb_arr[i].list_type)
after i has been set to indicate which table you are processing.
{
// Its not a long list!
}
else
{
objLb1->dc[0].lb_items[0] = 188; // <<< replaces 185 with 188
Not necessarily. If list_type != 0, the lb_items[0] could also be 0.
If you know what the values are, why not put them in the
initialization of lb_arr?
objLb1->dc[0].lb_items[1] = 180; // <<< replaces 184 with 180
objLb1->dc[0].lb_items[2] = 189; // <<< replaces 183 with 189
}
// For record #2 (Need to store 10 items in dynamic memory???)
Your first problem is you have no record 2. objLb1 points to memory
large enough for exactly one lb. If you know you need 10, then change
create_obj to allocate enough space. You would probably need to move
the assignment to member dc back into main.
If the quantity is not known until run-time, one approach is to keep
count of how many lb objects have been allocated and use realloc to
obtain more space. When you do that, your code objLb1->dc[0]... needs
to be changed to objLb1[i].dc[0]... You can do this by changing the
malloc in create_obj to realloc and passing in the count. This has
the additional virtue of making the first argument meaningful instead
of the waste it is now.
if(objLb1->dc[1].list_type)
{
//=====How do I store these 10 items?======
//When it comes time to use more
//long *temp; ?
//temp = x[i].storage; ?
//x[i].storage = realloc(temp, 10 * sizeof *x[i].storage); ?
objLb1->dc[0].x->storage[0] = 100;
//objLb1->dc[0].x->storage[1] = 101;
//objLb1->dc[0].x->storage[2] = 102;
//objLb1->dc[0].x->storage[3] = 103;
//objLb1->dc[0].x->storage[4] = 104;
//objLb1->dc[0].x->storage[5] = 105;
//objLb1->dc[0].x->storage[6] = 106;
//objLb1->dc[0].x->storage[7] = 107;
//objLb1->dc[0].x->storage[8] = 108;
//objLb1->dc[0].x->storage[9] = 109;
}
else
{
// Its not a short list!
At this point, it is a short list!
}
// For record #3 (Need to store 30 items in dynamic memory???)
if(objLb1->dc[2].list_type)
You need list_type to have more than two states.
{
//=====How do I store these 30 items?======
//When it comes time to use more
//long *temp; ?
//temp = x[i].storage; ?
//x[i].storage = realloc(temp, 10 * sizeof *x[i].storage); ?
30, not 10.
// put 30 items in dynamic memory!
}
else
{
// Its not a short list!
Yes it is.
}
// For record #4 (store 5 items directly in record #4)
if(objLb1->dc[3].list_type)
{