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
Related
I am attempting to dynamically allocate an array of the following struct at a particular address in memory. I use the pointer struct page_frame* memBlocks as the start to the array, but each access to the next element with memBlocks[i] in the for loop only moves 8 bytes. I checked the size of my struct in gdb which shows the expected 16 bytes, so why are accesses to the pointer behaving in this way?
struct page_frame{
struct page_frame* next; //Next node of linked list
int used;
};
struct page_frame* memBlocks;
memBlocks = (struct page_frame*)0xffffffff80000000 + physFree;
int indices = ((int)physEnd/4096)
for(int i = 0; i < indices; i++)
{
struct page_frame temp;
temp.used = 3;
temp.next = (struct page_frame*)&memBlocks[i+1];
memBlocks[i] = temp;
}
I was overwriting my structs by setting each element equal to temp. I was able to fix it with the following.
struct page_frame* memBlocks = (struct page_frame*)0xffffffff80000000 + physFree;
int indices = ((int)physEnd/4096);
//struct page_frame arr[physEnd];
for(int i = 0; i < indices; i++)
{
memBlocks[i].used = 1;
memBlocks[i].next = &memBlocks[i+1];
}
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 am trying to take input from console and add it to hash table.
But I'm getting Segmentation fault 11.
So, I debugged the program using gdb-apple.
It is showing that I'm trying access memory I cannot, using the pointer variable.
I think it is something obvious, but I'm missing it
This is what the gdb is displaying
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000008
0x0000000100000986 in CreateHashTable (size=200) at hashing.c:29
29 h->Table[i]->next = NULL;
Here is the code
Header File:
#define LOAD_FACTOR 20
#define INITIAL_SIZE 200
struct HashTable *CreateHashTable(int size);
int HashSearch(struct HashTable *h,int data);
int HashInsert(struct HashTable *h,int data);
int HashDelete(struct HashTable *h, int data);
void Rehash(struct HashTable *h);
int Hash(int data, int size);
struct ListNode
{
int key;
int data;
struct ListNode *next;
};
struct HashTableNode
{
int bcount;
struct ListNode *next;
};
struct HashTable
{
int tsize;
int count;
struct HashTableNode **Table;
};
Implementation file:
#include "hashing.h"
#include<stdio.h>
#include<stdlib.h>
struct HashTable *CreateHashTable(int size)
{
struct HashTable *h;
h = (struct HashTable *) malloc ( sizeof(struct HashTable) );
if(h == NULL)
{
printf("Memory Error");
return NULL;
}
h->tsize = (int) size/LOAD_FACTOR;
printf("h->tsize = %d",h->tsize);
h->count = 0;
h->Table = malloc ( ( sizeof(struct HashTableNode **) ) * (h->tsize) );
if( h->Table == NULL )
{
printf("Memory Error");
return NULL;
}
int i;
for( i=0 ; i < (h->tsize) ; i++)
{
h->Table[i]->next = NULL;
h->Table[i]->bcount = 0;
}
return h;
}
I would paste the rest of file, or Driver file, but I don't see it relevant.
Please tell me why I'm getting the segmentation fault 11
You allocated memory for array of pointers but you didn't allocate memory for members of this array.
for( i=0 ; i < (h->tsize) ; i++)
{
h->Table[i] = malloc(...); //put correct arguments here and check allocation
h->Table[i]->next = NULL;
h->Table[i]->bcount = 0;
}
Your problem is here:
struct HashTableNode **Table;
You want an array of nodes (not a 2d array), change to:
struct HashTableNode *Table;
also change
h->Table = malloc ( ( sizeof(struct HashTableNode **) ) * (h->tsize) );
to
h->Table = malloc(sizeof(struct HashTableNode) * h->tsize);
I think I want an array of pointers to nodes, don't I?
As pointed out by #WhozCraig, there is no reason for the additional level of indirection.
Example A (Pointer):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *a; /* pointer */
int i, n = 10;
a = malloc(n * sizeof(int)); /* space for 10 ints */
for (i = 0; i < n; i++) {
a[i] = i;
}
for (i = 0; i < n; i++) {
printf("%d\n", a[i]);
}
free(a);
return 0;
}
Example B (Pointer to pointer):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int **a; /* pointer to pointer*/
int i, n = 10;
a = malloc(n * sizeof(int *)); /* space for 10 pointer to ints */
for (i = 0; i < n; i++) {
a[i] = malloc(sizeof(int)); /* space for 1 int */
*a[i] = i;
}
for (i = 0; i < n; i++) {
printf("%d\n", *a[i]);
free(a[i]);
}
free(a);
return 0;
}
As you can see both do the same thing, but the first one requires less memory and the code is cleaner.
One way to make it easy to remember is:
int * can hold an array
int ** can hold a table (NROWS * NCOLS)
int *** can hold an array of tables
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
A struct like the following works fine, I can use t after calling malloc(sizeof(mystruct)):
struct mystruct {
MyDef *t[5];
};
I want to be able to dynamically set the length of the array of MyDef, like the following:
struct mystruct {
MyDef **t;
int size;
};
What do I need to do additionally to malloc(sizeof(mystruct)) to get this to work, so I can do TestStruct->t[3] = something? Just getting a segmentation fault!
Thanks!
EDIT with code that causes seg fault, unless I'm blind this seems to be what the answers are so far:
#include <stdio.h>
typedef struct mydef {
int t;
int y;
int k;
} MyDef;
typedef struct mystruct {
MyDef **t;
int size;
} MyStruct;
int main(){
MyStruct *m;
if (m = (MyStruct *)malloc(sizeof(MyStruct)) == NULL)
return 0;
m->size = 11; //seg fault
if (m->t = malloc(m->size * sizeof(*m->t)) == NULL)
return 0;
return 0;
}
struct mystruct *s = malloc(sizeof(*s));
s->size = 5;
s->t = malloc(sizeof(*s->t) * s->size);
m = (MyStruct*)malloc(sizeof(MyStruct)) == NULL
What that does. Calls malloc, compares return of malloc to NULL. Then assigns the result of that comparison(a boolean value) to m.
The reason it does that is because '==' has a higher precedence than '='.
What you want:
if ( (m = (MyStruct *)malloc(sizeof(MyStruct))) == NULL)
...
if ( (m->t = malloc(m->size * sizeof(*m->t))) == NULL)
That happens because you do not allocate memory for array itself, only for pointer to this array.
So, first you have to allocate mystruct:
struct_instance = malloc(sizeof(mystruct));
and then you have to allocate memory for array of pointers to MyDef and initialize pointer in your struct
struct_instance->size = 123;
struct_instance->t = malloc(sizeof(MyDef*) * struct_instance->size);