This the struct that I declared :-
struct page_table_entry {
struct addrspace* as;
vaddr_t va;
//page_state_t state;
int timestamp;
};
Now I want to dynamically allocate memory for an array of this. My implementation is here :-
struct page_table_entry **coremap = (struct page_table_entry**)
kmalloc(npages*sizeof(struct page_table_entry*));
int i;
for(i=0;i<npages;i++)
{
coremap[i] = (struct page_table_entry*)kmalloc(sizeof(struct page_table_entry));
coremap[i].va=(firstAddress+(i*PAGE_SIZE));
}
Its giving me an error on the last line where I am accesing the variable va. Error is:-
error: request for member `va' in something not a structure or union
You have an array of pointers to structs, not an array of structs.
In the line
coremap[i] = (struct page_table_entry*)kmalloc(sizeof(struct page_table_entry));
you cast your memory allocation to page_table_entry*, so coremap[i] is this pointer.
You access the actual struct via
coremap[i]->va=(firstAddress+(i*PAGE_SIZE));
coremap is a pointer to a pointer to a struct page_table_entry.
When you dereference it with coremap[i] you get a pointer to a struct page_table_entry.
You cannot use . on a pointer to a structure. You must use ->:
coremap[i]->va=(firstAddress+(i*PAGE_SIZE));
or
(*coremap[i]).va=(firstAddress+(i*PAGE_SIZE));
Aside from the obvious change to coremap[i]->va, you could change to an array of structs:
struct page_table_entry *coremap = (struct page_table_entry*)kmalloc(npages*sizeof(struct page_table_entry));
int i;
for(i=0;i<npages;i++)
{
coremap[i].va=(firstAddress+(i*PAGE_SIZE));
}
Related
I'm working with a few kernel modules (4.19.97) and I allocate struct my_sock like the following.
struct my_target {
union thingA { ... } a;
struct thingB *b;
};
struct my_sock {
struct sock sk;
// ...
struct my_target target;
};
struct my_sock *my_s;
my_s = my_sock_alloc();
// ...
my_s->sk.sk_prot->init(sk);
The above ends up calling this callback.
static int my_init(struct sock *sk)
{
// I do the following because I cannot pass in the allocated
// `struct my_sock` into this function.
struct my_sock *ms = my_sk(sk);
// I want to access my_s->my_target or any field within
// `struct my_target` here, but at this point, `ms` is
// pointing to the the first member of `struct my_sock`, and
// not the originally allocated `my_s`.
ms->target.a;
}
static inline struct my_sock* my_sk(const struct sock *s)
{
return container_of(s, struct my_sock, sk);
}
// Here's how my_s gets allocated. Note that this is not the same
// structure as the first member of `struct my_sock`.
struct my_sock* my_sock_alloc(void)
{
struct my_sock *sk = NULL;
sk = kmem_cache_zalloc(my_sk_cachep, GFP_KERNEL);
if (!sk)
return NULL;
return sk;
}
And here's the problem. The kernel has the code for container_of within include/linux/kernel.h which casts a member of a structure out to the containing structure, per the commentary.
When I use my_sk(sk), I get the pointer address of the first member of the containing struct. The problem is that this is a different address than my_s which I allocated in the very first line and I need the pointer to my_s in order to access the target member.
Thoughts as to how I might access my_s->target within the call my_init() (and not make things global)?
since sk is the very first field in struct my_sock, you can just cast the pointer and things should work:
struct my_sock *ms = (struct my_sock *)sk;
the extra work done in container_of is only needed when the "base" struct is not the first field.
Let's say I have the following struct and array of that struct:
struct Fileinfo {
int ascii[128]; //space to store counts for each ASCII character.
int lnlen; //the longest line’s length
int lnno; //the longest line’s line number.
char* filename; //the file corresponding to the struct.
};
struct Analysis fileinfo_space[8]; //space for info about 8 files
I want to have a function that will add a new struct to this array. It must take a void pointer to the position where to store the struct as an argument
int addentry(void* storagespace){
*(struct Fileinfo *)res = ??? //cast the pointer to struct pointer and put an empty struct there
(struct Fileinfo *)res->lnlen = 1; //change the lnlen value of the struct to 1
}
My questions are:
What goes in place of ??? I tried (Fileinfo){NULL,0,0,NULL} as per this Stackoverflow response. But I get `error: ‘Fileinfo’ undeclared (first use in this function)
How do I create a void pointer to the array? Is (void *)fileinfo_space correct?
I am required to use void * as the argument for the function for this assignment. It's not up to me.
Let's say you have some memory block passed as storagespace void pointer:
You have to define a constant to be able to initialize (unless you're using c++11), let's call it init. BTW your assignment value is wrong: first member is an array of int. You cannot pass NULL to it. Just zero-fill it like show below.
Then cast your void pointer into a pointer on your struct, then initialize by copying the init struct, modify at will...
int addentry(void* storagespace){
static const struct Fileinfo init = {{0},0,0,NULL};
struct Fileinfo *fi = (struct Fileinfo *)storagespace;
*fi = init; //cast the pointer to struct pointer and put an empty struct there
fi->lnlen = 1; //change the lnlen value of the struct to 1
}
Consider a pointer variable as defined below
struct socket_info
{
int hsocket;
int * buffer;
}
typedef struct socket_info * t_socket_info;
Now we I want to declare the pointer variable and use it as follow
t_socket_info t_socket;
How to allocate the memory for t_socket pointer variable
In C, you would do
t_socket = malloc(sizeof(struct socket_info));
or
t_socket = malloc(sizeof *t_socket);
t_socket=(socket_info *)malloc(sizeof(socket_info))
I'm trying to use an array of structs and everytime I try to assign a value to any struct, it gives me this error:
request for member 's' in something not a structure or union
My struct:
struct {
char s;
int lineNum;
} item;
I'm declaring it this way:
struct item * stack[100];
And then:
/* both lines gives me the error */
stack[0].s = 'a';
stack[0].lineNum = 1;
Am I missing something here?
You do not have a struct item.
stack is an array of 100 pointer to an as yet undefined struct.
Try
struct item {
char s;
int lineNum;
};
You need this:
struct item {
char s;
int lineNum;
} ;
...
struct item * stack[100];
...
stack[0]->s = 'a';
stack[0]->lineNum = 1;
but beware: you need to allocate memory for each item in stack. stack contains 100 pointers to struct items, but each of these pointers contains garbage (they all point to invalid memory).
For each element in stack you need to allocate memory like this stack[n] = malloc(sizeof struct item).
struct item stack[100] is what you want for your code that follows. What you have is an array of pointers, each of which if you wish to use, you will need to allocate, before your declaration.
You have not defined struct item. You currently have a single variable named item of an anonymous struct. It appears you forgot to include the typedef:
typedef struct { ... } a_t; // can use "a_t" as type.
struct a { ... }; // can use "struct a" as type.
typedef struct a { ... } a_t; // can use "struct a" or "a_t" as type.
stacks is not an array of items, it's an array of pointers to items, so you need to dereference them before attempting to use them:
(*(stack[0])).s = 'a';
(*(stack[0])).lineNum = 1;
I have this struct:
typedef struct Grades {
int grade1;
int grade2;
int grade3;
int grade4;
int grade5;
}
I created a pointer to a Grades struct using
struct Grades *pointer;
and I have a function() that returns a (void *) pointer to a specific Grades struct.
How do I set my pointer to that specific struct using the (void *) pointer?
I was thinking:
pointer = &function();
but that gives me an error: "'&' requires l-value
Any ideas? And by the way, I can't modify the function so...
If function() returns a pointer, you should be able to just do
pointer = function();
pointer = function();
If function() is returning a void pointer, you don't need to take the address of it, it's already a pointer pointing to a Grades struct.