C Programming: Segmentation fault at struct ptr. Memory alloc issue - c

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.

Related

how to initialize struct array members inside function by reference

im trying to make an array of struct and initialize struct array member, but I don't know how to access struct member, i used (st->ch)[t] = 'c'; and others similar syntax but i did not succeed.
best regards.
struct ST
{
char ch;
};
bool init(ST* st, int num)
{
st = (ST*)malloc(num * sizeof(ST));
if (st == NULL) return false;
for (int t = 0; t < num; t++) (st->ch)[t] = 'c';
return true;
}
int main()
{
ST* s = NULL;
init(s, 2);
putchar(s[1].ch);
}
You declared in main a pointer
ST* s = NULL;
that in C shall be declared like
struct ST* s = NULL;
because you declared the type specifier struct ST (that in C is not the same as just ST)
struct ST
{
char ch;
};
that you are going to change within a function. To do that you have to pass the pointer to the function by reference. That is the function declaration will look at least like
bool init( struct ST **st, int num );
and the function is called like
init( &s, 2);
if ( s ) putchar( s[1].ch );
The function itself can be defined like
bool init( struct ST **st, int num )
{
*st = malloc( num * sizeof( struct ST ) );
if ( *st )
{
for ( int i = 0; i < num; i++) ( *st )[i].ch = 'c';
}
return *st != NULL;
}
If you are using a C++ compiler then substitute this statement
*st = malloc( num * sizeof( struct ST ) );
for
*st = ( struct ST * )malloc( num * sizeof( struct ST ) );
When the array of structures will not be needed you should free the memory occupied by the array like
free( s );
You can access struct member using following:
st[t].ch
As mentioned by #kaylum st being a local variable in the init() and doesn't update the variable s in the main function hence an alternative could be you either pass the add the address of the variable s to init() or could just return the allocated memory as shown in the code snippet below. Instead of using bool as return type to check you can use the ST* as return type and if it returns NULL or mem address to get mem alloc status.
Also you would have to typedef the struct typedef struct ST ST; to be able to directly use the type as ST else you would have to stick to using struct ST
typedef struct ST
{
char ch;
}ST;
ST* init(int num)
{
ST *st;
// Create num elems of ST type
st = (ST*)malloc(num * sizeof(ST));
// return NULL is st unintialised
if (st == NULL) {
return st;
}
// Assign ch member variable of the 't'th st element wit 'c'
for (int t = 0; t < num; t++) {
st[t].ch = 'c';
}
return st;
}
int main()
{
ST* s;
// creates an array of size two of type st
s = init(2);
putchar(s[1].ch);
return 0;
}

How to allocate struct pointer inside a struct dynamically?

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

"Undeclared" value for value declared inside struct

I'm trying to implement/understand stacks and I keep getting "value undeclared" for something that is declared inside the struct that is supposed to represent the stack
#define EmptyTOS ( -1 )
#define MinStackSize ( 5 )
typedef struct StackRecord *Stack;
struct StackRecord
{
int Capacity;
int TopOfStack;
int *Array;
};
Stack CreateStack( int MaxElements )
{
Stack S;
S = malloc( sizeof( struct StackRecord ) );
S->Array = malloc( sizeof( int ) * MaxElements );
S->Capacity = MaxElements;
MakeEmpty( S );
return S;
}
void MakeEmpty( Stack S ){
S->TopOfStack = EmptyTOS;
}
void Push( int X, Stack S ){
S->Array[++TopOfStack] = X;
}
int main(){
Stack s1 = CreateStack(10);
return 0;
}
If I try to compile just this I get: In function ‘Push’: error: ‘TopOfStack’ undeclared
I don't understand why
It is because TopOfStack is not declared.
If you want to access the member variable of the object pointed at by S, you should write S->TopOfStack.

priority queue segmentation fault

I am using a priority queue with a double as the priority. I am guessing this is the cause of the issues. I used these numbers first with no issues.
34.365681
34.481879
34.539832
36.715120
I then used these numbers and had a segmentation fault.
45.411042
40.481879
37.702110
38.951187
struct PRIORITYQUEUE
{
int x_pq;
int y_pq;
double heuristic_pq;
int priority;
int info;
struct PRIORITYQUEUE *next;
}*start, *q, *temp, *new;
typedef struct PRIORITYQUEUE *N;
void insert(int x, int y, double heuristic)
{
int item;
double itprio;
//new = ( N* ) malloc( sizeof( N ) );
new = malloc( sizeof( N ) );
itprio = heuristic;
new->x_pq = x;
new->y_pq = y;
new->heuristic_pq = itprio;
if ( start == NULL || itprio < start->heuristic_pq )
{
new->next = start;
start = new;
}
else
{
q = start;
while ( q->next != NULL && q->next->heuristic_pq <= itprio )
q = q->next;
new->next = q->next;
q->next = new;
}
}
void del()
{
if ( start == NULL )
{
printf( "\nQUEUE UNDERFLOW\n" );
}
else
{
new = start;
printf( "\nDELETED ITEM IS %d\n", new->info );
start = start->next;
free( start );
}
}
void display()
{
temp = start;
if ( start == NULL )
printf( "QUEUE IS EMPTY\n" );
else
{
printf( "QUEUE IS:\n" );
while ( temp != NULL )
{
printf( "\t x is %d y is %d[heuristic=%lf] \n", temp->x_pq, temp->y_pq, temp->heuristic_pq );
temp = temp->next;
}
}
}
Your problem lies with this code:
typedef struct PRIORITYQUEUE *N;
:
new = malloc( sizeof( N ) );
The type N is a pointer to that structure of yours, not the structure itself. That means that sizeof(N) is likely to be much smaller than the structure, meaning that you're not allocating enough memory.
You could see this by inserting this immediately after the allocation:
printf ("%zd %zd\n", sizeof (N), sizeof (struct PRIORITYQUEUE));
and you'll probably see a series of lines of the form 4 32 or 8 32, showing that, while you've allocated four or eight bytes, you need 32.
That's what's causing your crashes. Now, as to how to fix it, it's simply making sure you allocate enough space for the structure and this can be done with either of:
new = malloc (sizeof (struct PRIORITYQUEUE));
new = malloc (sizeof (*N));
But the one I prefer is:
new = malloc (sizeof (*new));
The reason I prefer it is that it ties the allocation quantity to the variable you using. While the earlier two will handle any changes to the structure size, this one will even survive declaring new as a totally different structure without having to change information in multiple places.
By that I mean, if you change the type of new thus:
struct FASTER_PRIO_Q *new;
then you would be required to change the allocation statements as well for the first two cases. Not so for the third.

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

Resources