accessing Double pointer - c

typedef struct _WDF_USB_DEVICE_SELECT_CONFIG_PARAMS {
ULONG Size;
WdfUsbTargetDeviceSelectConfigType Type;
union {
struct {
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
PUSB_INTERFACE_DESCRIPTOR* InterfaceDescriptors;
ULONG NumInterfaceDescriptors;
} Descriptor;
struct {
PURB Urb;
} Urb;
struct {
UCHAR NumberConfiguredPipes;
WDFUSBINTERFACE ConfiguredUsbInterface;
} SingleInterface;
struct {
UCHAR NumberInterfaces;
PWDF_USB_INTERFACE_SETTING_PAIR Pairs;
UCHAR NumberOfConfiguredInterfaces;
} MultiInterface;
} Types;
} WDF_USB_DEVICE_SELECT_CONFIG_PARAMS, *PWDF_USB_DEVICE_SELECT_CONFIG_PARAMS;
WDF_USB_DEVICE_SELECT_CONFIG_PARAMS params;
typedef struct _USB_INTERFACE_DESCRIPTOR {
UCHAR bLength ;
UCHAR bInterfaceClass ;
UCHAR bInterfaceSubClass ;
} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR ;
Able to acess NumInterfaceDescriptors via -> params.Types.Descriptor.NumInterfaceDescriptors
I want to acess bInterfaceClass via WDF_USB_DEVICE_SELECT_CONFIG_PARAMS .
Please note that this structure is filled by the library I have to just access it

(*someIntDesc)->iInterface

IntDesc foo;
// somehow initialize foo to actually point to (a pointer to) a valid structure
(*foo)->iInterface = 10;

Deference it like this
(*intDesc)->iInterface

IntDesc is a type, not a variable. So the first thing you need to do is create a variable of the correct type:
IntDesc id;
Next, you'll need to have it point to allocated memory. I'm going to put everything on the stack, you may have other needs:
USB_INTERFACE_DESCRIPTOR usb;
PUSB_INTERFACE_DESCRIPTOR pusb = &usb;
id = &pusb;
Now that you have a valid pointer, you can go ahead an dereference it. Since this is a double pointer, you will need to dereference it twice:
(*(*id)).iInterface = 10;
Because C defines -> as a combination of * and ., you can express that more succinctly with:
(*id)->iInterface = 10;

From the name InterfaceDescriptors, it would appear to point to an array of pointers to the structure. So the more idiomatic way would be:
InterfaceDescriptors[0]->iInterface = 10;

Your code is quite wrong
NODE* ptr;
k.N.iInterface = 100;
ptr = (NODE*)malloc(sizeof(NODE));
And before accesing:
ptr->N1->iInterface
N1 should be initialized to something.

Related

Free the memory where a uintptr_t is pointing to

I have the following problem:
First of all I have struct:
struct Filehandler
{
const int id = 1;
};
Then I have two methods - one for creating a new Filehandler struct and one for deleting the struct. Because the whole code is part of a Webassembly Plugin for a Rust project, I have to use pointers.
So this is my method for allocating the struct:
uintptr_t newhandler() {
struct Filehandler* filehandler = (struct Filehandler*) malloc(sizeof(struct Filehandler));
uintptr_t *ptr = (uintptr_t *)&filehandler;
uintptr_t temp = (uintptr_t)ptr;
return temp;
}
I know this somehow looks confusing but I have to retrieve the address the pointer is pointing as value. Thats why im returning my pointer as value.
Now I want to create a function which deletes the struct. As parameter the function gets an uintptr_t:
void destroy_handler(uintptr_t ptr) {
........?
}
So my question is: Is it possible to delete the Struct filehandler, if I have a the pointer to it stored in a uintptr_t and give it as a value to the destroy_handler function. And if this is possible how do I do it?
Thank you guys!
const int id = 1; isn't valid C because you can't initialize members of a struct like that. In general, avoid const qualifiers of members but make an instance of the whole struct const instead.
uintptr_t newhandler() should be uintptr_t newhandler(void), the former is obsolete style and should not be used.
Casting the result of malloc is pointless. Consider struct Filehandler* filehandler = malloc (sizeof *filehandler); instead.
uintptr_t *ptr = (uintptr_t *)&filehandler; doesn't make any sense, you are casting the malloc:ed pointer's address which is a local variable. Drop the &.
uintptr_t temp = (uintptr_t)ptr; doesn't make any sense because you are casting the address of a local pointer again.
Fixed code should look something like:
struct Filehandler
{
int id;
};
const struct Filehandler FH = {.id = 1};
...
#include <stdlib.h>
uintptr_t newhandler (void)
{
struct Filehandler* filehandler = malloc(sizeof *filehandler);
if(filehandler == NULL)
{
return 0;
}
// optional line: memcpy(filehandler, &FH, sizeof FH);
return (uintptr_t)filehandler;
}
void destroy_handler(uintptr_t ptr)
{
free((void*)ptr);
}

Two dimensional array address

I have two structures as follows
typedef struct Rsp_s {
u8 code;
u8 Count;
}Rsp_t;
typedef struct Field_s {
u8 State;
u8 present;
u8 previous;
u8 event;
} Field_t
Then i have
Rsp_t *rsp;
Field_t data[3][7]
I want data[0][0] to follow rsp->Count.
How do i do that?
data = (Field_t *)(&(rsp->Count) +1);
does not do it.
When you declare a variable like this ...
int b[3][7];
... its memory location is assigned by the compiler if static or given memory from the stack if automatic, and therefore cannot be changed programatically. You can however access this memory, and read to and write from it, by using a pointer ...
int (*a)[7] = b;
The following are equivalent:
b[0][0] = b[1][1];
a[0][0] = a[1][1];
Your assignment is the wrong way round. You want to assign to a the address of b[0][0], so:
a = &b[0][0];

Use a struct in a header file [ C - Linux ]

I tried to use an external struct but when I compile my c code I obtained this message:
subscripted value is neither array nor pointer nor vector.
Why?
messaggio.h
struct Request {
struct {
u_int data_len;
float *data_val;
} data;
bool_t last;
};
typedef struct Request Request;
main.c
#include "messaggio.h"
int main(void){
struct Request x;
x.data[0] = 4.6;
printf("%f\n",x.data[0]);
return 0;
}
The x.data is a struct, so you cannot use [] with it. Maybe you want x.data.data_val[0].
Try this code:
struct Request x;
x.data.data_len = 5; // initialize the length, use any value you need
x.data.data_val = (float *) malloc(x.data.data_len * sizeof(float));
x.data.data_val[0] = 4.6
x.data is a structure and not an array.
Use x.data.data_val[0] if that is what you are trying to access. However, you have not allocated any memory for data_val. I believe you are trying to assign a number to data_len and will need to allocate the memory to hold data_len values in data_val.
The type of struct Request#data is an anonymous struct { u_int, float } and not an array. Thus you can't use the [] operator on it.
You probably wanted to do:
x.data.data_val[0]

Is it possible to return a pointer to a struct without using malloc?

I'm writing a Gameboy ROM using the GBDK, which has an unstable version of malloc that I'm unable to get working. I'm also unable to return a struct within a struct. That leaves me trying to return a pointer, which is why I'm wondering if there is a way to avoid using malloc when returning a struct pointer?
What I'm basically trying to do is that I want to be able to write something like this:
create_struct(struct_name, char member_x, char member_y);
This is the code I have written using malloc:
struct point {
char member_x;
char member_y;
};
struct point *makepoint(char member_x, char member_y) {
struct point *temp = malloc(sizeof(struct point));
temp->member_x = member_x;
temp->member_y = member_y;
return temp;
};
There are various valid ways to return a pointer (to a struct, or any type of object), but the only way to return a pointer to a new object that didn't exist before the function was called is to use malloc, realloc, calloc, aligned_alloc (C11), or some implementation-defined allocation function (e.g. mmap on POSIX systems, etc.).
Other ways you could return a valid pointer include:
A pointer to an object with static storage duration. Only once instance of such an object exists, so this is usually a bad way.
A pointer that was passed to the function as an argument for use as a place to store the result. This can often be a good approach, since you pass off responsibility for obtaining the storage to the caller.
A pointer to an object obtained from some sort of global pool. This could be a very good approach in embedded systems and game design for low-end gaming devices.
Is it possible to return a pointer to a struct without using malloc?
I. Technically, yes. You can make your struct static so that it survives function calls:
struct foo *bar()
{
static struct foo f = { 1, 2, 3 };
return &f;
}
But I doubt you actually want to do this (since this has funny side effects, read up on the meaning of the static keyword). You have several different possibilities:
II. The approach what the C standard library takes is always making the caller implicitly responsible for providing the struct and managing memory. So instead of returning a pointer, the function accepts a pointer to struct and fills it:
void dostuff(struct foo *f)
{
foo->quirk = 42;
}
III. Or return the struct itself, it doesn't hurt, does it (it can even be move-optimized):
struct foo bar()
{
struct foo f = { 1, 2, 3 };
return f;
}
So, choose your poison.
just do something like:
void makepoint(struct point *dest, char member_x, char member_y) {
dest->member_x = member_x; // you had these wrong in your code, by the way
dest->member_y = member_y;
}
The structure will need to be "allocated" elsewhere (probably on the stack is your best bet).
You could pass the struct as a parameter and have the function initialize it :
struct point *makepoint(struct point *pt, char x, char y) {
pt->x = x;
pt->y = y;
return pt;
}
and then call it like this :
struct point pt;
makepoint(&pt, 'a', 'b');
but then you might as well just have done :
struct point pt = { 'a', 'b' };
Note that in this case (struct point only occupies 2 bytes) you can return struct point instead of struct point *, (this should not be done with large structs)
#include <stdio.h>
struct point {
char member_x;
char member_y;
};
struct point makepoint(char member_x, char member_y)
{
struct point temp;
temp.member_x = member_x;
temp.member_y = member_y;
return temp;
}
int main(void)
{
struct point t = makepoint('a', 'b');
printf("%c %c\n", t.member_x, t.member_y);
return 0;
}
If it is not possible to get malloc() fixed, then you may just want to manage your own pre-allocated points, and limit the number of points that can be "created". You would need to alter your points a little to allow for easier management:
union free_point {
union free_point *next;
struct point data;
};
union free_point free_point_pool[MAX_POINTS];
union free_point *free_point_list;
struct point *makepoint(char member_x, char member_y) {
static int i;
union free_point *temp;
temp = 0;
if (i == MAX_POINTS) {
if (free_point_list) {
temp = free_point_list;
free_point_list = temp->next;
}
} else {
temp = free_point_pool + i++;
}
if (temp) {
temp->data.x = x;
temp->data.y = y;
}
return &temp->data;
};
Then, instead of calling free() on the result returned by makepoint(), you should create a new function to place it on the free_point_list.
void unmakepoint (struct point *p) {
union free_point *fp = (union free_point *)p;
if (fp) {
fp->next = free_point_list;
free_point_list = fp;
}
}
The simplest thing is just to return a structure that has been created using named initializers, and do so in an inline function, so that there is zero overhead:
static inline struct point makepoint(char x, char y) {
return (struct point) { .x = x, .y = y };
}
Then you can call it like this:
struct point foo = makepoint(10, 20);
Couldn't be simpler!

What does "request for member '*******' in something not a structure or union" mean?

Is there an easy explanation for what this error means?
request for member '*******' in something not a structure or union
I've encountered it several times in the time that I've been learning C, but I haven't got a clue as to what it means.
It also happens if you're trying to access an instance when you have a pointer, and vice versa:
struct foo
{
int x, y, z;
};
struct foo a, *b = &a;
b.x = 12; /* This will generate the error, should be b->x or (*b).x */
As pointed out in a comment, this can be made excruciating if someone goes and typedefs a pointer, i.e. includes the * in a typedef, like so:
typedef struct foo* Foo;
Because then you get code that looks like it's dealing with instances, when in fact it's dealing with pointers:
Foo a_foo = get_a_brand_new_foo();
a_foo->field = FANTASTIC_VALUE;
Note how the above looks as if it should be written a_foo.field, but that would fail since Foo is a pointer to struct. I strongly recommend against typedef:ed pointers in C. Pointers are important, don't hide your asterisks. Let them shine.
You are trying to access a member of a structure, but in something that is not a structure. For example:
struct {
int a;
int b;
} foo;
int fum;
fum.d = 5;
It may also happen in the following case:
eg. if we consider the push function of a stack:
typedef struct stack
{
int a[20];
int head;
}stack;
void push(stack **s)
{
int data;
printf("Enter data:");
scanf("%d",&(*s->a[++*s->head])); /* this is where the error is*/
}
main()
{
stack *s;
s=(stack *)calloc(1,sizeof(stack));
s->head=-1;
push(&s);
return 0;
}
The error is in the push function and in the commented line. The pointer s has to be included within the parentheses. The correct code:
scanf("%d",&( (*s)->a[++(*s)->head]));
I have enumerated possibly all cases where this error may occur in code and its comments below. Please add to it, if you come across more cases.
#include<stdio.h>
#include<malloc.h>
typedef struct AStruct TypedefedStruct;
struct AStruct
{
int member;
};
void main()
{
/* Case 1
============================================================================
Use (->) operator to access structure member with structure pointer, instead
of dot (.) operator.
*/
struct AStruct *aStructObjPtr = (struct AStruct *)malloc(sizeof(struct AStruct));
//aStructObjPtr.member = 1; //Error: request for member ‘member’ in something not
//a structure or union.
//It should be as below.
aStructObjPtr->member = 1;
printf("%d",aStructObjPtr->member); //1
/* Case 2
============================================================================
We can use dot (.) operator with struct variable to access its members, but
not with with struct pointer. But we have to ensure we dont forget to wrap
pointer variable inside brackets.
*/
//*aStructObjPtr.member = 2; //Error, should be as below.
(*aStructObjPtr).member = 2;
printf("%d",(*aStructObjPtr).member); //2
/* Case 3
=============================================================================
Use (->) operator to access structure member with typedefed structure pointer,
instead of dot (.) operator.
*/
TypedefedStruct *typedefStructObjPtr = (TypedefedStruct *)malloc(sizeof(TypedefedStruct));
//typedefStructObjPtr.member=3; //Error, should be as below.
typedefStructObjPtr->member=3;
printf("%d",typedefStructObjPtr->member); //3
/* Case 4
============================================================================
We can use dot (.) operator with struct variable to access its members, but
not with with struct pointer. But we have to ensure we dont forget to wrap
pointer variable inside brackets.
*/
//*typedefStructObjPtr.member = 4; //Error, should be as below.
(*typedefStructObjPtr).member=4;
printf("%d",(*typedefStructObjPtr).member); //4
/* Case 5
============================================================================
We have to be extra carefull when dealing with pointer to pointers to
ensure that we follow all above rules.
We need to be double carefull while putting brackets around pointers.
*/
//5.1. Access via struct_ptrptr and ->
struct AStruct **aStructObjPtrPtr = &aStructObjPtr;
//*aStructObjPtrPtr->member = 5; //Error, should be as below.
(*aStructObjPtrPtr)->member = 5;
printf("%d",(*aStructObjPtrPtr)->member); //5
//5.2. Access via struct_ptrptr and .
//**aStructObjPtrPtr.member = 6; //Error, should be as below.
(**aStructObjPtrPtr).member = 6;
printf("%d",(**aStructObjPtrPtr).member); //6
//5.3. Access via typedefed_strct_ptrptr and ->
TypedefedStruct **typedefStructObjPtrPtr = &typedefStructObjPtr;
//*typedefStructObjPtrPtr->member = 7; //Error, should be as below.
(*typedefStructObjPtrPtr)->member = 7;
printf("%d",(*typedefStructObjPtrPtr)->member); //7
//5.4. Access via typedefed_strct_ptrptr and .
//**typedefStructObjPtrPtr->member = 8; //Error, should be as below.
(**typedefStructObjPtrPtr).member = 8;
printf("%d",(**typedefStructObjPtrPtr).member); //8
//5.5. All cases 5.1 to 5.4 will fail if you include incorrect number of *
// Below are examples of such usage of incorrect number *, correspnding
// to int values assigned to them
//(aStructObjPtrPtr)->member = 5; //Error
//(*aStructObjPtrPtr).member = 6; //Error
//(typedefStructObjPtrPtr)->member = 7; //Error
//(*typedefStructObjPtrPtr).member = 8; //Error
}
The underlying ideas are straight:
Use . with structure variable. (Cases 2 and 4)
Use -> with pointer to structure. (Cases 1 and 3)
If you reach structure variable or pointer to structure variable by following pointer, then wrap the pointer inside bracket: (*ptr). and (*ptr)-> vs *ptr. and *ptr-> (All cases except case 1)
If you are reaching by following pointers, ensure you have correctly reached pointer to struct or struct whichever is desired. (Case 5, especially 5.5)
It may means that you forgot include a header file that define this struct/union.
For example:
foo.h file:
typedef union
{
struct
{
uint8_t FIFO_BYTES_AVAILABLE : 4;
uint8_t STATE : 3;
uint8_t CHIP_RDY : 1;
};
uint8_t status;
} RF_CHIP_STATUS_t;
RF_CHIP_STATUS_t getStatus();
main.c file:
.
.
.
if (getStatus().CHIP_RDY) /* This will generate the error, you must add the #include "foo.h" */
.
.
.
can also appear if:
struct foo { int x, int y, int z }foo;
foo.x=12
instead of
struct foo { int x; int y; int z; }foo;
foo.x=12
I saw this when I was trying to access the members.
My struct was this:
struct test {
int a;
int b;
};
struct test testvar;
Normally we access structure members as
testvar.a;
testvar.b;
I mistook testvar to be a pointer and did this.
testvar->a;
That's when I saw this error.
request for member ‘a’ in something not a structure or union
My ridiculous experience is that I incorrectly put '.' instead of ','.
printf("%c". ch);

Resources