Re: vasam
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)
{
// Its not a long list!
}
else
{
objLb1->dc[0].lb_items[0] = 200; // <<< replaces 85 with 200
objLb1->dc[0].lb_items[1] = 201; // <<< replaces 4 with 201
objLb1->dc[0].lb_items[2] = 202; // <<< replaces 204 with 202
objLb1->dc[0].lb_items[3] = 203; // <<< replaces 11 with 203
objLb1->dc[0].lb_items[4] = 204; // <<< replaces 28 with 204
}
// 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;
}
======================================
In summary I need to store long list types of different sizes when a record
requires a long list type. Also, in the lb_arr[], I would like to be able to
innitialize the location of where the list will be stored.
Thankyou all for your help much appreciated!
I am a little discouraged and confused.
STOP CODING. START THINKING.
If you can't explain in English (without referencing C terms like long
and struct) what your program is supposed to do, you will not be able
to code it. I'll try to start it for you:
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?
You are in love with nested structures. It's killing you. Stop it.
Why do you need an lb whose only purpose is to point to an lb_table?
Why do you need a listx whose only purpose is to point to some longs?
What percentage of your lb_table will be short? Is it worth hard
coding a long[5] if most will need an additional allocation?
--
Remove del for email