Re: vasam
Robby 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
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
which is a member of the tag_lb_table. If the list_type is true, then we must
allocate some memory dynamically to store a certain amount of longs. The
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 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.
Let me go through it one step at a time. Record #1 has:
{ 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
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;
typedef struct tag_lb_table
{
long lb_items[5];
short list_type;
//struct t_listx *x;
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()
{
long a, b;
lb MyRef3;
lb *objLb1 = &MyRef3;
listx x[] =
{
{malloc(5 * sizeof(long))},
{malloc(5 * sizeof(long))}
//...
};
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?
{ 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)
{
// Its not a long list!
}
else
{
objLb1->dc[0].lb_items[0] = 188; // <<< replaces 185 with 188
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???)
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!
}
// For record #3 (Need to store 30 items in dynamic memory???)
if(objLb1->dc[2].list_type)
{
//=====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); ?
// put 30 items in dynamic memory!
}
else
{
// Its not a short list!
}
// 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.
Wow, Robby, it sure seems like you're doing things the hard way a lot here! Let me make sure I am working on a correct assumption
that you need to restrict this to the C language, and not use C++?
I don't get the point of having a separate struct type t_listx just to hold a pointer. I also don't understand why you want this x
array.
In your problem description, you seem pretty certain about the number of longs needed for each record... is this a fixed value? Are
you dealing with purely static data that doesn't change?
I believe there are a handful of much better ways to solve your ultimate problem, but it's not quite clear what's at the root of
this design. Rather than follow my temptation to nitpick little things I see wrong with what you've code already, I think it's
really time for you to give a better idea of where this data comes from, and just exactly how well-known things will be at runtime.