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];
}
Related
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
For part of my C data structures assignment, I am tasked with taking an array of pointers to nodes of 2 doubly linked lists (one representing the main service queue, and the other representing a "bucket" of buzzers ready to be reused or used for the first time in the queue), doubling the size, while keeping the original contents in tact. The idea is that each node has an ID associated which corresponds to the number index of the pointer array map. So for example, the pointer in index 3 will always point to the node whose ID is 3. The boolean inQ is for something unrelated to this issue.
I've written most of the code, but it seems to be functioning incorrectly (it changes all the original pointers to the last node in the list before the array resizing) So, since the starting size of the array is 10 elements, when I print out the contents after the function, it displays 9 9 9 9 9 9 9 9 9 9.
Here are the structs im using:
typedef struct node {
int id;
int inQ;
struct node *next;
struct node *prev;
}NODE;
typedef struct list
{
NODE *front;
NODE *back;
int size;
} LIST;
//referred to as SQ in the separate header file
struct service_queue
{
LIST *queue;
LIST *bucket;
NODE **arr;
int arrSize;
int maxID;
};
Here is the function in question:
SQ sq_double_array(SQ *q)
{
NODE **arr2 = malloc(q->arrSize * 2 * sizeof(NODE*));
int i;
//fill the first half of the new array with the node pointers of the first array
for (i = 0; i < q->arrSize; i++)
{
arr2[i] = malloc(sizeof(NODE));
if (i > 0)
{
arr2[i - 1]->next = arr2[i];
arr2[i]->prev = arr2[i - 1];
}
arr2[i]->id = q->arr[i]->id;
arr2[i]->inQ = q->arr[i]->inQ;
arr2[i]->next = q->arr[i]->next;
arr2[i]->prev = q->arr[i]->prev;
}
//fill the second half with node pointers to the new nodes and place them into the bucket
for (i = q->arrSize; i < q->arrSize * 2; i++)
{
//Point the array elements equal to empty nodes, corresponding to the inidicies
arr2[i] = malloc(sizeof(NODE));
arr2[i]->id = i;
arr2[i]->inQ = 0;
//If the bucket is empty (first pass)
if (q->bucket->front == NULL)
{
q->bucket->front = arr2[i];
arr2[i]->prev = NULL;
arr2[i]->next = NULL;
q->bucket->back = arr2[i];
}
//If the bucket has at least 1 buzzer in it
else
{
q->bucket->back = malloc(sizeof(NODE));
q->bucket->back->next = arr2[i];
q->bucket->back = arr2[i];
q->bucket->back->next = NULL;
}
}
q->arrSize *= 2;
q->arr = arr2;
return *q;
}
Keep in mind this must only be done in c, which is why im not using 'new'
You could use the realloc function:
void *realloc(void *ptr, size_t size);
Quoted from the man pages:
The realloc() function changes the size of the memory block pointed to
by ptr to size bytes. The
contents will be unchanged in the range from the start of the region up to the minimum of the old
and new sizes. If the new size is larger than the old size, the added memory will not be initialā
ized. If ptr is NULL, then the call is equivalent to malloc(size), for all values of size; if
size is equal to zero, and ptr is not NULL, then the call is equivalent to free(ptr). Unless ptr
is NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc(). If the
area pointed to was moved, a free(ptr) is done.
I am trying to create a Hash Map in C. Below is the code. When I try to
assign value to the elements of Darray ( each of which is a pointer to a Node) I am getting a segmentation fault ( i.e. at line 23 and24). Could anybody help in pointing out where am I going wrong.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
}Node;
typedef struct Map{
struct Node** Darray;
} Map;
#define SIZE 10
int main()
{
int i=0;
Map* M = malloc(sizeof(Map));
M->Darray = (struct Node**)malloc(sizeof(Node*)*SIZE);
for (i =0;i < SIZE;i++){
M->Darray[i]->data =0;
M->Darray[i]->next =NULL;
}
}
You allocate space for SIZE pointers to Node, but don't initialize these in any way, so when you access M->Darray[i] in M->Darray[i]->data you get segmentation fault because value of M->Darray[i] has not been set.
You need to allocate space for each node before using it:
for (i = 0; i < SIZE; i++) {
M->Darray[i] = malloc(sizeof(Node));
M->Darray[i]->data = 0;
M->Darray[i]->next = NULL;
}
Depending on your needs, you could also change Darray to be an array of nodes instead of node pointers, so you can allocate space for all nodes at once:
struct Node* Darray;
...
M->Darray = malloc(sizeof(Node) * SIZE);
for (i = 0; i < SIZE; i++) {
M->Darray[i].data = 0;
M->Darray[i].next = NULL;
}
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);
Here is my struct
struct ListItem{
int data;
struct ListItem *next;
};
Assuming the first node of the linked list will have data = 0, I want to write a for loop that creates a linked list of size 5 but I'm not sure how to work
I tried the following
int main(int argc, char* argv[]){
struct ListItem a;
a.data = 0;
for (int i = 1; i < 5; i++){
struct ListItem *pointer = &a;
struct ListItem nextnode;
nextnode.data = i;
a.next = &nextnode;
pointer = pointer->next;
}
}
But the result is
a.data = 0
and a.next->data = 4
Don't modify a. Take a temp node starting as a. Make it's next point to the new node and then set temp node to the new node. Also allocate dynamically in heap. Otherwise the memory will get deallocated after every loop run
struct ListItem a[5] = { {0, NULL}};
struct ListItem *pointer = &a[0];
for (int i = 0; i < 5; i++){
a[i].data = i;
if(i != 5 -1)
a[i].next = &a[i+1];
}