I am currently doing a project to simulate loading and storing info like a computer Cache.
I used malloc to load a struct into memory but I don't know how to retrieve that information again.
For any line, I need to be able to call up a particular line in the cache and see if it causes a "hit or a miss" like a cache would.
struct cache {int s; int E; int b;}; //my struct
//creating a similated cache in memory.
struct cache** c1 = (struct cache**) malloc( pow(2,ssize) * Esize * sizeof(struct cache));`
Basically when you do
struct cache** c1 = (struct cache**) malloc( pow(2,ssize) * Esize * sizeof(struct cache)).
That is a pointer to pointer of struct cache. It is similar to an array of pointer to struct cache but it is not in your stack memory but in your heap memory. Nonetheless, you did it wrong. Each index of your struct cache ** suppose to be equal to the size of the pointer of struct cache. The code below probably explain everything.
After get space for struct cache **, each of its index you suppose to assign it with a pointer to struct * cache or malloc a pointer to struct cache with the size equal to the size struct cache. The code below, I created 10 index using malloc. So 0 - 9.
#include <stdlib.h>
#include <stdio.h>
struct cache {int s; int E; int b;}; //my struct
//creating a similated cache in memory.
int main(){
// Each index equal the size of a pointer to struct cache and there is 10 index
struct cache** c1 = (struct cache**) malloc( sizeof( struct cache* ) * 10 );
// Each index is a pointer to struct cache with the malloc size it pointing
// to equal to struct cache
c1[0] = (struct cache*) malloc( sizeof(struct cache) );
// Any later index would have to use malloc or assign a pointer to c1
c1[0]->s = 1;
c1[0]->E = 2;
c1[0]->b = 3;
printf("%d %d %d", c1[0]->s,
c1[0]->E,
c1[0]->b );
return 0;
}
Related
I was looking forward to make an array of struct just like [ obj, obj, obj ].
I got this struct:
struct obj {
char name[MAX_NAME];
char desc[MAX_TEXT];
bool asible;
};
How can I make it?
I tried
struct obj **objInRoom = malloc(sizeof(struct obj));
But when I iterate in it, it doesnt have anything :D
I chose this solution because I need to put that array of struct into this struct:
struct room {
struct obj **objts; //HERE
int qntty_objts;
struct interact **interacts;
int qntty_interacts;
};
If you need to have a double pointer for some reason, then you can do something like this struct obj *objInRoom = malloc(sizeof(struct obj)); and then assign address of objInRoom to your struct room->objts=&objInRoom.
struct obj **objInRoom = malloc(sizeof(struct obj));
If I simplifies, in your try you are allocating an area for a struct and trying to assign its address to a 'struct obj address' address holder which is struct obj**. But you should use struct obj * to hold the address of newly allocated area.
Which in this case your struct room should be like this:
struct room {
struct obj *objts; //struct obj** to struct obj*
int qntty_objts;
struct interact **interacts;
int qntty_interacts;
};
You should assign your newly allocated area like this:
struct obj *objInRoom = (struct obj*)malloc(sizeof(struct obj));
But in this case you only allocated the area for one struct obj element. To increase this area you can take the backup of your previous data and allocate new area for more size. For example to increase your allocated area two times:
//cap is integer defined before to hold capacity information of array
struct obj *backup = (struct obj*)malloc(2*cap*sizeof(struct obj));
for(int i = 0; i < cap; ++i)
backup[i] = objInRoom[i];
free(objInRoom); //to prevent memory leak, because we allocated new area for our incremented sized array.
objInRoom = backup;
cap *= 2;
Or you can simply use realloc to increase your array capacity if an allocation happened before with malloc or calloc, realloc creates an array with desired size and holds the previous data:
objInRoom = (struct obj*)realloc(objInRoom, 2*cap*sizeof(struct obj))
Note: Always cast your malloc operation to your desired pointer type because it returns 'void *' for default.
Note 2: Always check outputs from malloc, realloc and calloc; they return NULL in case of error.
If the size of a structure pointer is 4 or say 8 bytes, how can it properly allocate the required memory for its data members in Dynamic Memory Allocation. This is my code:
#include<stdio.h>
typedef struct node{
char a[10];
char b[10];
char c[10];
int f;
struct node* next;
}node;
int main()
{
node* temp;
int d= sizeof(node *);
printf("Size of structure pointer = %d",d);
temp= (node*)malloc(sizeof(node*));
int c = sizeof(temp);
printf("Size of Temp = %d\n",c);
}
```````````````````
/*
Here both Temp and node* is having a size of 8 bytes.
But the size of the structure 'node' is 38 bytes(total size of the members).
So how can the pointer Temp allocate that much memory if its size is just 8 bytes ?
*/
Because you don't store data in pointers. Pointers point at data allocated elsewhere, hence the name "pointer". sizeof(node*) is wrong and the size of the pointer itself is irrelevant.
You should do
temp = malloc(sizeof *temp); // equivalent of sizeof(Node)
...
free(temp);
This is the pointer to the node struct, you don't need to allocate space for it. It can point to the node structure.
struct node *node_ptr;
If you want to store node structure at some pointer, you need to allocate space for the node structure NOT THE POINTER
node *node_data = malloc(sizeof(struct node));
You don't need to cast the result from the malloc, it is bad { see casting for malloc }
Pointer is just the pointer. It you are a tourist guide in the war museum and use the pointer to show the tank - what is the weight of the pointer in your hand? The weight of the wooden stick or the weight of the tank?
First lets understand about malloc:
Malloc is a function which allocates memory in a HEAP part of RAM. If we define a variable, usually it gets allocated in STACK part of RAM.
temp = (int*)malloc(n*sizeof(int));
this code allocates a memory in HEAP.
Now lets understand about ponters:
consider the following code.
int a;
int *p;
p=&a;
in the about line of code the pointer 'p' is storing the address of the variable 'a'.
Depending on the word length of your system(32bit or 64bit), the size of the pointer variable 'p' changes. It can be 2bytes or 4bytes or 8bytes. 8bytes is because in 64bit machine, "long int" can takes 8bytes.
Now lets understand about both pointers with structure:
struct value{
int a;
int b;
char c;
};
Since above code is a definition of structure, memory won't get allocated.
struct value s;
now the memory gets allocated in Stack.
struct value *s;
s = (struct value*)malloc(sizeof(struct value));
here the memory gets allocated in Heap.
Even though 's' is structure pointer it still stores the address of the whole structure 'value', it's size will be 4/8. It points to whole structure not the particular member of structure.
The general structure 's' will have the data part of all its members. So the size will be 5 or 9 depending of the machine and the padding.
struct s{
int a; /* 4 bytes */
char b; /* 1 byte */
/* 1 padding byte */
short c; /* 2 bytes */
};
Refer Data Structure Padding
So I am learning about data structure stack in my college, howsoever I have some doubts in its implementation and the memory it occupies.
Below is a small code which I have written for it: -
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <stdbool.h>
struct stack
{
int *array;
int top;
int max_size;
};
struct stack createStack(int size)
{
struct stack *Stack = malloc(sizeof(struct stack)); //line 1
Stack -> max_size = size; //line 2
Stack -> top = -1; //line 3
Stack -> array = calloc(Stack -> max_size, sizeof(int)); //line 4
return *Stack;
}
int main()
{
int size; //Here lets say that size = 5
scanf("%d", &size);
printf("%ld", sizeof(createStack(size)));
return 0;
}
Here I have defined Stack through struct stack as seen below in this portion of the code: -
struct stack
{
int *array;
int top;
int max_size;
};
Now the memory which would be occupied by the above struct stack should be: -
8 bytes for int *array
4 bytes for int top
4 bytes for int max_size
Therefore total memory occupied\allocated should be 16 bytes.
Now lets come to the second portion of code which helps in creation of stack: -
struct stack createStack(int size)
{
struct stack *Stack = malloc(sizeof(struct stack)); //line 1
Stack -> max_size = size; //line 2
Stack -> top = -1; //line 3
Stack -> array = calloc(Stack -> max_size, sizeof(int)); //line 4
return *Stack;
}
Here in line 1 we have allocated the sizeof struct stack(16 bytes) in structure variable *Stack. Hence size of * Stack is 16 bytes.
In line 2 and in line 3 values are initialised.
Now my question come from line 4
In line 4 we allocated 20 bytes to int *array (considering max_size = 5)
Now shouldn't the size of structure variable *Stack be 28 bytes considering that int *array now occupies 20 bytes instead of 8 bytes ?
When I run the above code, it still mentions that the sizeof structure variable *Stack is 16 bytes. What am i missing here?
Now shouldn't the size of structure variable *Stack be 28 bytes considering that int *array now occupies 20 bytes instead of 8 bytes?
No. The size of array is still 8 bytes. It just contains the memory address of a separate chunk of memory that is 20 bytes in size. That separate chunk is not part of *Stack and does not contribute to its size.
In fact, sizeof(createStack(size)) does not call your function, so no memory is ever allocated. sizeof only cares about the type of its operand expression. Since createStack is declared as returning a struct stack, sizeof createStack(...) is equivalent to sizeof (struct stack). All of this is resolved at compile time.
Similarly, if you do
char arr[1000];
char *ptr = &arr[0];
then sizeof ptr is still 8 because ptr is declared as char * and sizeof (char *) is 8. That's all that matters.
By the way, if you were to actually call createStack, it would leak memory:
struct stack *Stack = malloc(sizeof(struct stack));
...
return *Stack;
The first line allocates memory and stores the address in Stack. However, this address does not leave the function. Only a copy of the struct itself is returned (via return *Stack). The program has now lost track of the pointer returned by malloc and can never free it.
Fix:
struct stack Stack;
Stack.max_size = size;
Stack.top = -1;
Stack.array = calloc(Stack -> max_size, sizeof(int));
return Stack;
The size of a structure is just the amount of memory used for the structure itself, not the memory for any things pointed to be members of the structure.
The fact that array is given a value that points to more memory does not change the structure or its size.
sizeof reports only the memory required for a particular object. It does not report all memory you have associated or linked to in some way.
typedef struct{
char id[15];
int count;
}hashtag;
typedef struct node{
hashtag *hashtag;
struct node*next;
}*link;
I'm writing a program to read hashtags from a sentence, and I want to store them in a list. I've already defined this two structures, and I can read and pass the hashtags to the function below but I need help allocating memory in order to copy the string to the list.
void check_insert(char newh[]){
link x;
//malloc to allocate memory for the string I want to copy
strcpy(x->hashtag->id, newh);
x->hashtag->count += 1;
head = insert_end(head, x->hashtag); //head is a global variable that points to the 1st element of the list
}
You should allocate and initialize the pointer x in check_insert, it is undefined behavior to dereference it and access its members without allocation first:
void check_insert(char newh[]){
link x = malloc(sizeof *x);
x->hashtag = malloc(sizeof *x->hashtag);
// strcpy(x->hashtag->id, newh); <-- UB if newh is larger than 14 in size
x->hashtag->id[0] = '\0';
strncat(x->hashtag->id, newh, sizeof(x->hashtag->id));
x->hashtag->count = 1;
head = insert_end(head, x->hashtag);
}
So I am working on a project in C where we need to implement malloc and free (meaning, we CANNOT use any C memory management functions such as malloc() or free()). This is only a code snippet, but it includes all relevant parts.
struct block_header
{
int size;
};
typedef struct FList_elem
{
struct block_header * header;
struct list_elem elem;
} FLelem;
void * manual_malloc(size_t size)
{
freeBlock = (FLelem *) mem_sbrk(newsize);
freeBlock->header = (struct block_header *) freeBlock;
freeBlock->header->size = newsize;
}
When allocating a new "block" of memory, we represent it via a structure FList_elem. In order to "allocate memory" for the struct, we point it at a memory address returned by mem_sbrk (works just like sbrk()). My question is, how do we establish memory for variables like size? Initially it's address is 0x0, and so assignments or references to it cause seg faults. Does it need to be a pointer so that we can set it's address, and then the value?
Instead of your original code, which stores a pointer to block_header inside the FList_elem structure, you can just embed the whole block_header structure inside the FList_elem structure:
struct block_header
{
int size;
};
typedef struct FList_elem
{
/* OLD code: struct block_header * header; */
/* Better code: block_header is embedded inside FList_elem structure */
struct block_header header;
struct list_elem elem;
} FLelem;
In this way, you don't need to allocate block_header separately: it's just there with the rest of FList_elem bytes.
And to set the size field (and any other attribute you may add to your block header) you can just do:
freeBlock->header.size = newsize;
When allocating the requested size, you need to add the header elements - and the pointer to the next block (eventually - the size can be computed with pointer difference as a space optimization... if this is embedded staff they are 4 bytes per block saved).
Since I think there are some incongruences, I have reported here my interpretation (not tested) of what you are trying to do:
struct block_header
{
int size;
};
typedef struct FList_elem
{
struct block_header header; // removed a * here: size is in place
struct Flist_elem *elem; // added a * here: that's the pointer to the next block.
} FLelem;
FLelem *memory_list = 0; // added a pointer for the global list - right?
void * manual_malloc(size_t newsize) // renamed as newsize here
{
freeBlock = (FLelem *) mem_sbrk(newsize + sizeof(FLelem));
freeBlock->header.size = newsize;
freeBlock->header.elem = memory_list;
memory_list = freeBlock;
// inserted freeBlock at the head of memory_list;
return (void*)(freeBlock+1); // +1 to skip the header as a return address
}
The caller of the function will have returned the space after the header.
Your manual_free() function will take as an argument this returned memory pointer, and it will need to subtract and go back a freeblock in memory in order to find the header and to release the block, and than you will need some sort of tree (bit tree) to keep of track of the holes left free... If you need to handle dynamic memory - and that's where it start being interesting.
Hope I have not done errors and that it's clear enough!
#include <stdlib.h>
struct st *x = malloc(sizeof *x);
Note that:
x must be a pointer
no cast is required
include appropriate header