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];
Related
I have a struct initialized on a stack, and i want to write data in memory right after the struct and make a pointer inside a struct point to that data.
I know it is achievable on the stack/heap with uninitialized structure using malloc(sizeof(struct) + additional size) or alloca(). but can i perform initialization of a data after the struct is already initialized on the stack? and can i perform this initialization inside a initializator function?
Simple example:
struct TEST {
wchar_t* itest;
};
void init_struct(struct TEST* test) {
// point to the end of the struct
char* walk_ptr = (char*)test + sizeof(test);
test->itest = (wchar_t*)walk_ptr;
// initialize data after the struct
...
}
int main(void) {
struct TEST test;
init_struct(&test);
return 0;
}
You could do this by embedding the structure inside another structure to reserve memory for the extra data:
int main(void)
{
struct { struct TEST test; wchar_t data[NumberOfElements]; } S;
init_struct(&S.test);
…
}
However, the code in init_struct adds an incorrect size, sizeof(test), to the pointer. You likely wanted to add sizeof (struct Test), or, equivalently, sizeof *test, since you want to get past the struct TEST that test points to, not past a struct TEST * that test is.
However, even adding the correct size of the structure would not guarantee strictly conforming C code, since C implementations may insert padding between structure members. Properly we would add the offset of the data member. To do that, we nwould eed to give the structure a tag and then either make the structure definition visible to init_struct or pass the offset to init_struct. However, it is easier just to pass the address of the extra data:
void init_struct(struct TEST *test, wchar_t *data)
{
test->itest = data;
}
int main(void)
{
struct { struct TEST test; wchar_t data[NumberOfElements]; } S;
init_struct(&S.test, S.data);
…
}
Of course, a pointer can point anywhere, and there is no apparent reason the data should be immediate after the structure, so we can disconnect them:
int main(void)
{
struct TEST test;
wchar_t data[NumberOfElements];
init_struct(&test, data);
…
}
I have a pointer *p that points to a struct S.
S has various fields.
Is it possible to assign structure S to the structure pointed to by *p
using only one assignment?
OR,
do I need to assign the fields, one by one?
This example assigns a struct using a pointer and one statement.
int main(void) {
struct Foo {
char a;
int b;
double c;
} *foo, *bar;
foo->b = 10;
bar = foo; /* now bar->b=10 as well */
}
Let's say that I was given a struct and I need to assign all of it's attributes to a particular address. The code below is giving me a conditional error, but i'm not trying to evaluate it.
struct header block_o_data;
block_o_data.a = 1;
block_o_data.b = 2;
void* startingAddress = sbrk(0);
&block_o_data = *address;
Please let me know what im doing wrong.
In the assignment to block_o_data, you're taking its address and trying to assign a value to it. The address of a variable is not an lvalue, meaning the expression cannot appear on the left side of an assignment.
You need to declare a pointer to a struct, then assign it the address of where the values actually live:
struct header *block_o_data;
void* startingAddress = sbrk(0);
block_o_data = startingAddress;
Suppose you have a struct like this:
struct mystruct {
int a;
char b;
};
then you probably need something like this:
// A pointer variable supposed to point to an instance of the struct
struct mystruct *pointer;
// This is a general address represented by void*
void *addr = some_function(0);
// Cast that general address to a pointer varibale pointing to
// an instance of the struct
pointer = (struct mystruct *) addr;
// Use it!
printf("%d", pointer->a);
I'm writing a C program in which I define two types:
typedef struct {
uint8_t array[32];
/* struct A's members */
...
} A;
typedef struct {
uint8_t array[32];
/* struct B's members, different from A's */
...
} B;
Now I would like to build a data structure which is capable of managing both types without having to write one for type A and one for type B, assuming that both have a uint8_t [32] as their first member.
I read how to implement a sort of polymorphism in C here and I also read here that the order of struct members is guaranteed to be kept by the compiler as written by the programmer.
I came up with the following idea, what if I define the following structure:
typedef struct {
uint8_t array[32];
} Element;
and define a data structure which only deals with data that have type Element? Would it be safe to do something like:
void f(Element * e){
int i;
for(i = 0; i < 32; i++) do_something(e->array[i]);
}
...
A a;
B b;
...
f(((Element *)&a));
...
f(((Element *)&b));
At a first glance it looks unclean, but I was wondering whether there are any guarantees that it will not break?
If array is always the first in your struct, you can simply access it by casting pointers. There is no need for a struct Element. You data structure can store void pointers.
typedef struct {
char array[32];
} A;
typedef struct {
void* elements;
size_t elementSize;
size_t num;
} Vector;
char* getArrayPtr(Vector* v, int i) {
return (char*)(v->elements) + v->elementSize*i;
}
int main()
{
A* pa = malloc(10*sizeof(A));
pa[3].array[0] = 's';
Vector v;
v.elements = pa;
v.num = 10;
v.elementSize = sizeof(A);
printf("%s\n", getArrayPtr(&v, 3));
}
but why not have a function that works with the array directly
void f(uint8_t array[32]){
int i;
for(i = 0; i < 32; i++) do_something(array[i]);
}
and call it like this
f(a.array)
f(b.array)
polymorphism makes sense when you want to kepp
a and b in a container of some sorts
and you want to iterate over them but you dont want to care that they are different types.
This should work fine if you, you know, don't make any mistakes. A pointer to the A struct can be cast to a pointer to the element struct, and so long as they have a common prefix, access to the common members will work just fine.
A pointer to the A struct, which is then cast to a pointer to the element struct can also be cast back to a pointer to the A struct without any problems. If element struct was not originally an A struct, then casting the pointer back to A will be undefined behavior. And this you will need to manage manually.
One gotcha (that I've run into) is, gcc will also allow you to cast the struct back and forth (not just pointer to struct) and this is not supported by the C standard. It will appear to work fine until your (my) friend tries to port the code to a different compiler (suncc) at which point it will break. Or rather, it won't even compile.
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.