Allocating dynamic array of structures within a structure - c

I have the following structures:
struct date {
int year;
int month;
int day;
};
struct person{
char name[64];
struct date birthday;
};
struct aop {
int max;
struct person **data;
};
I tried malloc for data within aop structure like this: (no errors occurred here)
struct aop *create_aop(int max) {
struct aop *s = malloc(sizeof(struct aop));
s->max = max;
s->data = malloc((sizeof(struct person)) * max);
return s;
}
But when I tried accessing "data" in other part of the code, such as this:
a->data[len]->birthday.year = birthday.year;
I got errors.
Am I doing malloc the wrong way, or am I accessing the data incorrectly?
Thank you in advance!

In aop structure you do not need double pointer for struct person. so
struct aop {
int max;
struct person **data;
};
change struct person **data;
to
struct person *data;
And while using that use it as below way.
a->data[len].birthday.year = birthday.year;

Field data in your aop structure is array of poiters, so at first you need to allocate memory for pointers:
s->data = malloc((sizeof(struct person*)) * max);
And then in loop you need to allocate memory for each structure:
for(i = 0; i < max; i++) {
s->data[i] = malloc(sizeof(struct person));
}

I've tried to create the same structure here, and I couldnt acess that structure Person.
Since you're willing to create multi person entries, how about creating a linked list?
Like:
struct aop {
int max;
struct person **data;
};
struct person{
char name[64];
struct date birthday;
struct person *nextPerson;
};
Probably it will work.

Am I doing malloc the wrong way, or am I accessing the data incorrectly?
Yes. Study this incredibly informative diagram:
Type *****var = malloc (sizeof(Type****) * n_items);
/* ----- ---- */
/* | | */
/* +---> n stars +---> n-1 stars */
If you have more than one star, you are not done yet. You need to allocate the data at the next level of indirection:
for (i = 0; i < n_items; ++i)
{
var[i] = malloc (sizeof(Type***) * n_items_level2);
/* --- */
/* | */
/* +---> n-2 stars */
If you still have stars, you are not done yet. You need to allocate the data at the next level of indirection in a nested loop:
for (j = 0; j < n_items_level2; ++j)
{
var[i][j] = malloc (sizeof(Type**) * n_items_level3);
and so on until you run out of stars.

Related

Allocation of double struct pointer

I have the following Hash_table and Hash_bucket structs
typedef struct Hash_Table{
struct Bucket** bucket;
}Table;
typedef struct Bucket{
struct Bucket* next;
int num;
}Bucket;
I want to allocate 5 Hash Tables which i do like this,
Table** hash_tables = malloc(sizeof(Table*)* 5);
for(int i = 0; i <=4 ; i++){
hash_tables[i] = NULL;
}
To my knowledge, what I have done up to here is correct, and I want to proceed allocating the Hash Tables in my code. As i did with the double pointer above, my allocation for the Hash Table
hash_table[0] = malloc(sizeof(Table));
hash_table[0]->bucket = malloc(sizeof(Bucket*)*10); /* line 2 that is problematic*/
I allocate the size for a Hash_Table and then 10 Hash_Bucket pointers. However, I am having leaks and NOT because I free the memory wrongly. The line 2 of the allocation seems to be redundant (?) and if I replace the Hash_Table with
typedef struct Hash_Table{
struct Bucket* bucket[10];
}Table;
, then the line 2 is not needed, everything works perfect and memory is free'd. I really am clueless as to what I am doing wrong. I've found the mistake, but don't see the mistake in the first place. Thank you all.
The Code you posted without the "line 2 is redundant" part should look like this right:
typedef struct Bucket {
struct Bucket* next;
int num;
} Bucket;
typedef struct Hash_Table {
struct Bucket** bucket;
} Table;
int main(void)
{
// Create hashtable
Table** hash_tables = malloc(sizeof(Table*) * 5);
for (int i = 0; i <= 4; i++) {
hash_tables[i] = NULL;
}
// Create Bucket
hash_tables[0] = malloc(sizeof(Table));
hash_tables[0]->bucket = malloc(sizeof(Bucket*)*10); /* line 2 that is problematic*/
free(hash_tables[0]->bucket);
free(hash_tables[0]);
free(hash_tables);
return 0;
}
If you add the right free's at the bottom you shouldn't have memory leaks.
At least Valgrind says so.
Note: for every written malloc in your code, you need at least 1 free

Declaring memory for a struct pointer array in c

I have a struct in c as follows:
typedef struct edgenode
{
int value;
struct edgenode * next;
};
I wish to create an array of pointer of edgenodes.
So, I can do edgenode * array[50].
But, how do I go about allocating memory dynamically for this?
Will it be,
edgenode ** array = malloc(sizeof(edgenode)*50)?
You can do like this
edgenodes * array = malloc(50 * sizeof *array);
You can initilize it by NULL as follows
for(i = 0; i < 50; ++i)
array[i] = NULL;
For allocating memory for each instance you need
for(i = 0; i < 50; ++i)
array[i] = malloc(sizeof *array[i]);
edgenode *array[50];
for (size_t i = 0; i < sizeof array / sizeof *array; i++)
{
array[i] = malloc(sizeof **array);
/* add code to check for malloc failure */
}
You are allocating first the list of pointers, so:
edgenode ** array = (edgenode **) malloc(sizeof(edgenode *) * 50);
And then, for each one:
array[i] = (edgenode *) malloc(sizeof(edgenode));
Given your example code:
typedef struct edgenode
{
int value;
struct edgenode * next;
};
I wish to create an array of pointer of edgenodes. So, I can do edgenode * array[50].
But, how do I go about allocating memory dynamically for this? Will it be,
edgenode ** array = malloc(sizeof(edgenode)*50)?
My suggested response:
Using a typedef is a very poor idea,
including that you have not given a reference name for the typedef.
a much better coding would be:
struct edgenode
{
int value;
struct edgenode * next;
};
Then, your question is a bit unclear on your final target.
If you mean that you want a local array of pointers to 50 instances of the
struct edgenode
where the 50 instances of the struct are in dynamic memory (the heap).
then the following will work nicely:
struct edgenode *array[50] = {NULL}; // declare array and init to null
for( int i=0; i<50; i++)
{
array[i] = (struct edgenode*)malloc( sizeof(struct edgenode) );
if( NULL == array[i] )
{ // then, malloc failed
... handle malloc failure
}
memset( array[i], 0x00, sizeof( struct edgenode ) );
}
However, the above yields 50 separate dynamic memory segments,
so 50 different free() calls would need to be made
and where LOTS of overhead and unused memory will be wasted
a better idea is:
$define edgenodeNum (50)
struct edgenode *edgenodePtr =
(struct edgenode*)malloc(sizeof(struct edgenode)*edgenodeNum );
if( NULL == edgenodePtr )
{
.... handle malloc failure
}
memset( edgenodePtr, 0x00, (sizeof( struct edgenode ) * edgenodeNum) )
for( int i=0; i<edgenodeNum; i++ )
{
array[i] = &(edgenodePtr[i]);
}
where there is very little wasted overhead/dynamic memory
and where only one free() will need to be performed

Unfamiliar C systax - declaring variables after a struct

#include "stdio.h"
void main( )
{
struct {
char initial;
int age;
int grade;
} kids[12], *point, extra;
I am following the tutorial from here http://www.gatesit.org/gitdownloads/C&DS.pdf page 813-22 and I don't quite understand what kids[12], *point, extra; means. From what I know you can initialize variables of the struct after the definition of it like that but why is there an array size 12, a pointer and extra?
Here is the code following it.
int index;
for (index = 0; index < 12; index++)
{
point = kids + index;
point->initial = 'A' + index;
point->age = 16;
point->grade = 84;
}
kids[3].age = kids[5].age = 17;
kids[2].grade = kids[6].grade = 92;
kids[4].grade = 57;
for (index = 0; index < 12; index++)
{
point = kids + index;
printf("%c is %d years old and got a grade of %d\n",
(*point).initial, kids[index].age, point->grade);
}
extra = kids[2]; /* Structure assignment */
extra = *point; /* Structure assignment */
}
struct mystruct {
char initial;
int age;
int grade;
} kids[12], *point, extra;
is equivalent to:
struct mystruct {
char initial;
int age;
int grade;
};
struct mystruct kids[12];
struct mystruct *point;
struct mystruct extra;
In your particular case, your struct doesn't have a tag name, so you actually can't create any instances of it afterwards - this is the only way you could do it, since it's unnamed.
Since here the struct is being defined inside a function, and its definition will only be available in that function, then it's likely you won't need to define any more instances of it, so there's no disadvantage of not having a name. On the other hand, other than having one less name in the tag namespace (and therefore avoiding the possibility of hiding a tag name at file scope), there's no particular advantage to it, either.
struct {
char initial;
int age;
int grade;
} kids[12], *point, extra;
This struct is unnamed.
This creates an array of 12 of this struct, named kids, a pointer to this type of struct named point, and another one of these structs named extra.
For a one-off structure, used only in a few limited places, this is acceptable. In a larger usage case, I would consider this kind of "sloppy", and would prefer to see something like this:
typedef struct {
char initial;
int age;
int grade;
} student_t;
int main() {
student_t kids[12]; // 12 students in the class
student_t* pStudent; // A pointer to a student_t
student_t extra; // The new kid
}
This basically defined an array of 12 elements of the defined struct kids[12], another variable that is a single pointer to the defined struct *point and finally a single instance of the struct extra.
Since the struct doesn't have a name, I suppose you'd have to define all of them at once next to the struct definition.
Equivalently, it could've been something like this:
struct kid {
char initial;
int age;
int grade;
};
struct kid kids[12];
struct kid *pointer;
struct kid extra;
You are declaring a 12 element array of the struct, a variable that is of the struct type, and a pointer to the struct. Then the code shows the different ways in which those types of variables can be used to access the inner pieces of the struct, and how the items can be assigned among each other.

how can i create a dynamic array of a hash table in c

i have the following bucket entry structure and hash table set up
typedef struct Hash_Entry
{
struct Hash_Entry *next;
void *key_Data;
unsigned key_hash;
char key[5];
} Hash_Entry;
typedef struct Hash_Table
{
struct Hash_Entry **bucketPtr; /* Buckets in the table */
int size; /* Actual size of array. */
int numEntries; /* Number of entries in the table. */
int mask; /* Used to select bits for hashing. */
} Hash_Table;
I want to create an array(or a dynamic array) of this Hash_Table so that when I feel the table is full I can create another table instead of re sizing it
Something like:
void hash_table_init(Hash_Table *table, size_t entries)
{
size_t i;
table->size = 0;
table->numEntries = entries;
table->bucketPtr = malloc(table->numEntries * sizeof *table->bucketPtr);
for(i = 0; i < table->numEntries; i++)
table->bucketPtr[i] = NULL;
table->mask = 0; /* Not sure how to initialize this. */
}
I don't quite see the point of leaving the initial buckets as pointers, I'd probably just do
typedef struct {
...
Hash_Entry *buckets;
...
} Hash_Table;
Assuming that most buckets will actually be used, so why not have them. :)
you can create an array using malloc from stdlib
Hash_Table* array = (Hash_Table*)malloc(sizeof(Hash_Table) * 100);
and when the array is full you can do a realloc.
you can have a look at:
Create dynamic sized array of user defined structure

c programming: need fresh eyes to look at this [demo code != homework]

Essentially I want qPtr[0] to hold sPtr[0]
struct myQueue{
struct sample* node;
int front;
int size;
int numElements;
};
struct sample{
int field1[5];
char field2[10];
}
int main(){
struct myQueue* qPtr = malloc(10 * sizeof(struct myQueue);
struct sample* samplePtr = malloc(10 * sizeof(struct sample); //assume this array has been initialized
enqueue(qPtr, samplePtr[0]); //this does not work
}
//returns 1 if enqueue was successful
int enqueue(struct myQueue* qPtr, struct sample* sPtr){
qPtr->node[(qPtr->front + qPtr->numElements) % qPtr->size] = sPtr; //code pertains to circular array implementation of queues
return 1;
}
I've been at it for about 2 hours now and would appreciate some clarification on what I'm doing wrong conceptually. thank you!
samplePtr[0] gives the object itself, not a pointer to the object. Try sending &samplePtr[0] or samplePtr itself. enque function, second parameter expects a type of struct sample* and not struct sample.
How about:
enqueue(qPtr, &samplePtr[0]);
The second parameter to enqueue() takes a pointer to a struct sample.
Your code has 2 fundamental problems.
you're passing a struct sample object to enqueue() instead of a pointer to a struct sample. this should be caught by the compiler.
you're setting up an array of queue structures instead of having a single queue structure object that manages an array of pointers to the objects that are on the queue. This is a design problem.
Your code should probably look more like:
struct myQueue{
struct sample* node;
int front;
int size;
int numElements;
};
struct sample{
int field1[5];
char field2[10];
}
struct myQueue q = {0};
int enqueue(struct myQueue* qPtr, struct sample* sPtr);
int main(){
// get memory to hold a collection of pointers to struct sample:
q.node = calloc(10, sizeof(struct sample*));
q.size = 10;
// allocate a sample
struct sample* samplePtr = malloc(sizeof(*samplePtr));
// put the sample on the queue
enqueue(qPtr, samplePtr);
}
//returns 1 if enqueue was successful
int enqueue(struct myQueue* qPtr, struct sample* sPtr){
qPtr->node[(qPtr->front + qPtr->numElements) % qPtr->size] = sPtr; //code pertains to circular array implementation of queues
return 1;
}

Resources