Basic C question, concerning memory allocation and value assignment
- by VHristov
Hi there,
I have recently started working on my master thesis in C that I haven't used in quite a long time. Being used to Java, I'm now facing all kinds of problems all the time. I hope someone can help me with the following one, since I've been struggling with it for the past two days.
So I have a really basic model of a database: tables, tuples, attributes and I'm trying to load some data into this structure. Following are the definitions:
typedef struct attribute
{
int type;
char * name;
void * value;
} attribute;
typedef struct tuple
{
int tuple_id;
int attribute_count;
attribute * attributes;
} tuple;
typedef struct table
{
char * name;
int row_count;
tuple * tuples;
} table;
Data is coming from a file with inserts (generated for the Wisconsin benchmark), which I'm parsing. I have only integer or string values. A sample row would look like:
insert into table values (9205, 541, 1, 1, 5, 5, 5, 5, 0, 1, 9205, 10, 11, 'HHHHHHH', 'HHHHHHH', 'HHHHHHH');
I've "managed" to load and parse the data and also to assign it. However, the assignment bit is buggy, since all values point to the same memory location, i.e. all rows look identical after I've loaded the data. Here is what I do:
char value[10]; // assuming no value is longer than 10 chars
int i, j, k;
table * data = (table*) malloc(sizeof(data));
data->name = "table";
data->row_count = number_of_lines;
data->tuples = (tuple*) malloc(number_of_lines*sizeof(tuple));
tuple* current_tuple;
for(i=0; i<number_of_lines; i++)
{
current_tuple = &data->tuples[i];
current_tuple->tuple_id = i;
current_tuple->attribute_count = 16; // static in our system
current_tuple->attributes = (attribute*) malloc(16*sizeof(attribute));
for(k = 0; k < 16; k++)
{
current_tuple->attributes[k].name = attribute_names[k];
// for int values:
current_tuple->attributes[k].type = DB_ATT_TYPE_INT;
// write data into value-field
int v = atoi(value);
current_tuple->attributes[k].value = &v;
// for string values:
current_tuple->attributes[k].type = DB_ATT_TYPE_STRING;
current_tuple->attributes[k].value = value;
}
// ...
}
While I am perfectly aware, why this is not working, I can't figure out how to get it working. I've tried following things, none of which worked:
memcpy(current_tuple->attributes[k].value, &v, sizeof(int));
This results in a bad access error. Same for the following code (since I'm not quite sure which one would be the correct usage):
memcpy(current_tuple->attributes[k].value, &v, 1);
Not even sure if memcpy is what I need here...
Also I've tried allocating memory, by doing something like:
current_tuple->attributes[k].value = (int *) malloc(sizeof(int));
only to get "malloc: * error for object 0x100108e98: incorrect checksum for freed object - object was probably modified after being freed." As far as I understand this error, memory has already been allocated for this object, but I don't see where this happened. Doesn't the malloc(sizeof(attribute)) only allocate the memory needed to store an integer and two pointers (i.e. not the memory those pointers point to)?
Any help would be greatly appreciated!
Regards,
Vassil