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
Related
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
I currently have a struct Struct1 which has a pointer to Struct2 that gets allocated multiple times based on some conditions in the code. I tried to allocate it test->Struct2Pair[i] = malloc(sizeof(struct Struct2));this way but it seems to fail. Any idea what I am doing wrong?
Here is a simplified version of what I'm trying to do.
struct Struct2 {
int x;
int y;
};
struct Struct1 {
struct Struct2 *Struct2Pair;
int val;
};
int main()
{
struct Struct1 *test = malloc(sizeof(struct Struct1));
for ( int i = 0; i < 5; i++ )
{
test->Struct2Pair[i] = malloc(sizeof(struct Struct2));
}
return 0;
}
Thanks!
In order to make Struct2Pair to point 5 consecutive memory object of type Struct2 you must allocate a 5*sizeof(Struct2). so in latter part of code you can access it as an array of size 5.
You must do null check for the return value of malloc.
struct Struct1 *test = malloc(sizeof(struct Struct1));
// |-----change is here and here--------------|
// v v
test->Struct2Pair = malloc(sizeof(struct Struct2) * 5);
//access can be as follows for all the index from 0 to 4
test->Struct2Pair[2].x = 10;
test->Struct2Pair[2].y = 20;
For better visualization refer this and this.
The issue you are having is located within the for loop and the number of available Struct2s in the test->Struct2Pair array.
You hadn't allocated any space for test->Struct2Pair before placing Struct2s into it
test->Struct2Pair[i] = malloc(sizeof(struct Struct2));
Then loop through more indexes then are available for the test->Struct2Pair array
for ( int i = 0; i < 5; i++ )
You may consider adding another variable to store the size of the test->Struct2Pair array:
int size = 5;
struct Struct1 *test = malloc(sizeof(struct Struct1));
test->Struct2Pair = malloc(size * sizeof(struct Struct2));
for ( int i = 0; i < size; i++ )
{
test->Struct2Pair[i].x = 0;
test->Struct2Pair[i].y = 0;
}
Reference on malloc:
https://en.cppreference.com/w/c/memory/malloc
I am getting segfault during runtime at:
I am trying to build this cache memory model in C.
So, the code compiles fine but I am getting segfault during runtime.
I tracked it down to this line:
cache->set[i]->block = (Block *) malloc( cache->numSets * sizeof( Block ) );
I tried making Block as an array inside of Set struct. But that gives other issues and infact gives the same segmentation fault as well.
typedef struct CacheMemory* Cache;
typedef struct Set_* Set;
typedef struct Block_* Block;
struct Block_ {
int valid;
int tag; // int *tag;
int dirty;
};
struct Set_ {
int numBlocks;
Block *block;
};
struct CacheMemory {
<snip>
Set *set;
};
Cache cache;
cache = (Cache) malloc(sizeof ( struct CacheMemory ) );
cache->set = (Set *) malloc( numSets * sizeof( Set ) );
for (i=0; i<cache->numSets; i++) {
//for (j = 0; j < cache->blockSize; j=j+1) {
// Note: I get segfault at line below during runtime
cache->set[i]->block = (Block *) malloc( cache->numSets *sizeof( Block ) );
//cache->set[i]->block[j] = (Block_) malloc (sizeof(Block_) );
// }
}
Set is a pointer to struct Set_, so your malloc
cache->set = (Set *) malloc( numSets * sizeof( Set ) );
reserves pointers, not struct Set_-objects.
Rewriting it as
cache->set = (Set *) malloc( numSets * sizeof( struct Set_ ) );
should help at least around this issue.
Say I have this struct
typedef struct list
{
int index
node *arr[]
}
Is there any way to assign the size of the node array when creating the struct of type list?
If you are allocating objects dynamically, then you can use flexible arrays, which are part of C99 and later:
struct list
{
int index;
size_t num_elements;
node * arr[]; // note the empty "[]"
};
Usage:
struct list * p = malloc(sizeof(struct list) + n * sizeof(node *));
p->index = 101;
p->num_elements = n;
for (size_t i = 0; i != p->num_elements; ++i)
{
p->arr[i] = create_random_pointer();
}
// ...
free(p);
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.