define code :
#include <stdio.h>
#include <string.h>
typedef int count_t;
typedef struct ptid_t {
short index;
short ioffset;
unsigned char type;
unsigned char networkType;
} ptid_t;
typedef union ptid_lst {
count_t count;
ptid_t item[1];
} plist_t;
main code :
int main(void) {
plist_t test;
memset(&test, 0x0, sizeof(plist_t));
test.count = 0xABCDABCD;
printf("%x\n", test.count);
printf("%x\n", test.item[0].index);
printf("%x\n", test.item[0].ioffset);
return 0;
}
console output :
abcdabcd
ffffabcd
ffffabcd
I just trying to change struct first value 'count' but other variables are changed.
The change value is 'count' in plist_t. but, why index and ioffset variables are changed both?
Because of this situation, I try to get the variable's address and result :
0x80479f4
0x80479f4
0x80479f6
The 'count' variable and item[0] struct has same address. why occured this situation?
In oppsite case are same too.
int main(void) {
plist_t test;
memset(&test, 0x0, sizeof(plist_t));
test.item[0].index = 0xabcd;
test.item[0].ioffset = 0xabc0;
printf("%x\n", test.count);
printf("%x\n", test.item[0].index);
printf("%x\n", test.item[0].ioffset);
return 0;
}
console output:
abc0abcd
ffffabcd
ffffabc0
Because plist_t isn't a struct, it's a union
In C, each member of a union starts at the same memory address.
If you want to change them independently, simply convert plist_t into a struct instead:
typedef struct ptid_lst {
count_t count;
ptid_t item[1];
} plist_t;
Related
I have a struct like the following:
struct Foo {
unsigned int id;
unsigned int flag_1 : 1;
unsigned int flag_2 : 1;
unsigned int flag_3 : 1;
// Some arbitrary number of further flags. Code is
// automatically generated and number will vary.
// Notably, it may be more than an int's worth.
int some_data;
float some_more_data;
// ...
};
From time to time, I need to reset all the flags to zero while preserving the rest of the struct. One way is obviously to set each flag to 0 individually, but it feels like there ought to be a way to do it in one fell swoop. Is that possible?
(Note that I am open to not using bit fields, but this is code that will sometimes run on memory-contrained systems, so the memory savings are very appealing.)
Edit:
There is a similar question here: Reset all bits in a c bitfield
However, the struct in that question is entirely bitfields. I cannot simply memset the entire struct to zero here, and the other answer involving unions is not guaranteed to work, especially if there are more than an int's worth of flags.
Just use a separate struct for the flags:
struct Foo_flags {
unsigned int flag_1 : 1;
unsigned int flag_2 : 1;
unsigned int flag_3 : 1;
// ...
};
struct Foo {
unsigned int id;
struct Foo_flags flags;
int some_data;
float some_more_data;
// ...
};
Or even a simpler nested struct:
struct Foo {
unsigned int id;
struct {
unsigned int flag_1 : 1;
unsigned int flag_2 : 1;
unsigned int flag_3 : 1;
// ...
} flags;
int some_data;
float some_more_data;
// ...
};
Then, later in your code:
struct Foo x;
// ...
x.flags.flag_1 = 1;
// ...
memset(&x.flags, 0, sizeof(x.flags));
With some minor adjustments, you can use the offsetof macro to find the beginning and end of the "flag" data within the structure, then use memset to clear the relevant memory. (Note that you cannot use offsetof directly on bitfields, hence the addition of the flag_beg member!)
Here's a working example:
#include <stdio.h>
#include <stddef.h> // defines offsetof
#include <string.h> // declares memset
struct Foo {
unsigned int id;
unsigned int flag_beg; // Could be unsigned char to save space
unsigned int flag_1 : 1;
unsigned int flag_2 : 1;
unsigned int flag_3 : 1;
unsigned int flag_end; // Could be unsigned char to save space
// Some arbitrary number of further flags. Code is
// automatically generated and number will vary.
// Notably, it may be more than an int's worth.
int some_data;
float some_more_data;
// ...
};
#define FBEG (offsetof(struct Foo, flag_beg))
#define FEND (offsetof(struct Foo, flag_end))
int main()
{
struct Foo f;
f.id = 3; f.flag_1 = 1; f.flag_2 = 0; f.flag_3 = 1;
f.some_data = 33; f.some_more_data = 16.2f;
printf("%u %u %u %u %d %f\n", f.id, f.flag_1, f.flag_2, f.flag_3, f.some_data, f.some_more_data);
memset((char*)(&f) + FBEG, 0, FEND - FBEG);
printf("%u %u %u %u %d %f\n", f.id, f.flag_1, f.flag_2, f.flag_3, f.some_data, f.some_more_data);
return 0;
}
I want to print out and intiliaze a Structure with a pointer and give it to a another function.
My Problem is: How can i intiliaze the structure with the variable name 'register' and print it out to test and see my values and adresses?
My Programms goal is basically to simulate a CPU. Therefore i have 3 pointers for the Orders, Stack and the Calculator (its a task given by our teacher).
But im not so good with structures and pointers
#include<stdio.h>
#include<stdint.h>
#include<stdbool.h>
struct reg {
unsigned char pc; // Befehlszeiger
unsigned char sp; // Stapelzeiger
unsigned char fa; // Flags + Akkumulator
};
bool cpu(struct reg *registers, unsigned char data[128], uint16_t cmd[256]);
int main(){
unsigned char data[128];
uint16_t cmd[256];
cmd[127] = 12;
data[127] = 'D';
data[128] = 'Z';
struct reg *registers = { '1', '2', '3'};
printf("The number before function: %d\n", registers->pc);
cpu(registers, data, cmd);
return 0;
}
bool cpu(struct reg *registers, unsigned char data[128], uint16_t cmd[256])
{
printf("The number in function: %d\n", registers->pc);
return 0;
}
Because the program says:
|20|warning: initialization makes pointer from integer without a cast [-Wint-conversion]|
20|note: (near initialization for 'registers')|
20|warning: excess elements in scalar initializer|
|20|note: (near initialization for 'registers')|
c|20|warning: excess elements in scalar initializer|
c|20|note: (near initialization for 'registers')|
To make it work rewrite the code as follows :
struct reg registers = { '1', '2', '3'}; // "registers" isn't a pointer
printf("The number before function: %d\n", registers.pc); // "." instance of a struct
cpu(®isters, data, cmd);// pass the address of "registers"
If you want the dinamic allocation of the memory you can do this:
#include<stdio.h>
#include<stdint.h>
#include<stdbool.h>
#include<stdlib.h>
struct reg {
unsigned char pc; // Befehlszeiger
unsigned char sp; // Stapelzeiger
unsigned char fa; // Flags + Akkumulator
};
bool cpu(struct reg *registers, unsigned char data[128], uint16_t cmd[256]);
int main(){
unsigned char data[128];
uint16_t cmd[256];
cmd[127] = 12;
data[127] = 'D';
data[128] = 'Z';
struct reg *registers;
registers = (struct reg*)malloc(sizeof(struct reg));
registers->pc = '1';
registers->sp = '2';
registers->fa = '3';
printf("The number before function: %d\n", registers->pc);
cpu(registers, data, cmd);
if(registers){
free(registers);
}
return 0;
}
bool cpu(struct reg *registers, unsigned char data[128], uint16_t cmd[256])
{
printf("The number in function: %d\n", registers->pc);
return 0;
}
else, if you don't need dinamic allocation of memory:
#include<stdio.h>
#include<stdint.h>
#include<stdbool.h>
struct reg {
unsigned char pc; // Befehlszeiger
unsigned char sp; // Stapelzeiger
unsigned char fa; // Flags + Akkumulator
};
bool cpu(struct reg *registers, unsigned char data[128], uint16_t cmd[256]);
int main(){
unsigned char data[128];
uint16_t cmd[256];
cmd[127] = 12;
data[127] = 'D';
data[128] = 'Z';
struct reg registers = { '1', '2', '3'};
printf("The number before function: %d\n", registers.pc);
cpu(®isters, data, cmd);
return 0;
}
bool cpu(struct reg *registers, unsigned char data[128], uint16_t cmd[256])
{
printf("The number in function: %d\n", registers->pc);
return 0;
}
Suppose I have the following (made up) definition:
typedef union {
struct {
unsigned int red: 3;
unsigned int grn: 3;
unsigned int blu: 2;
} bits;
uint8_t reg;
} color_t;
I know I can use this to initialize a variable that gets passed to a function, such as :
color_t white = {.red = 0x7, .grn = 0x7, .blu = 0x3};
printf("color is %x\n", white.reg);
... but in standard C, is it possible to instantiate a color_t as an immediate for passing as an argument without assigning it first to a variable?
[I discovered that yes, it's possible, so I'm answering my own question. But I cannot promise that this is portable C.]
Yes, it's possible. And the syntax more or less what you'd expect. Here's a complete example:
#include <stdio.h>
#include <stdint.h>
typedef union {
struct {
unsigned int red: 3;
unsigned int grn: 3;
unsigned int blu: 2;
} bits;
uint8_t reg;
} color_t;
int main() {
// initializing a variable
color_t white = {.bits={.red=0x7, .grn=0x7, .blu=0x3}};
printf("color1 is %x\n", white.reg);
// passing as an immediate argument
printf("color2 is %x\n", (color_t){.bits={.red=0x7, .grn=0x7, .blu=0x3}}.reg);
return 0;
}
If I have a struct in C that has an integer and an array, how do I initialize the integer to 0 and the first element of the array to 0, if the struct is a member another struct so that for every instance of the other struct the integer and the array has those initialized values?
Initialisers can be nested for nested structs, e.g.
typedef struct {
int j;
} Foo;
typedef struct {
int i;
Foo f;
} Bar;
Bar b = { 0, { 0 } };
I hope this sample program helps....
#include <stdio.h>
typedef struct
{
int a;
int b[10];
}xx;
typedef struct
{
xx x1;
char b;
}yy;
int main()
{
yy zz = {{0, {1,2,3}}, 'A'};
printf("\n %d %d %d %c\n", zz.x1.a, zz.x1.b[0], zz.x1.b[1], zz.b);
return 0;
}
yy zz = {{0, {0}}, 'A'}; will initialize all the elements of array b[10] will be set to 0.
Like #unwind suggestion, In C all instances created should initialized manually. No constructor kind of mechanism here.
You can 0-initialize the whole struct with {0}.
For example:
typedef struct {
char myStr[5];
} Foo;
typedef struct {
Foo f;
} Bar;
Bar b = {0}; // this line initializes all members of b to 0, including all characters in myStr.
C doesn't have constructors, so unless you are using an initializer expression in every case, i.e. write something like
my_big_struct = { { 0, 0 } };
to initialize the inner structure, you're going to have to add a function and make sure it's called in all cases where the structure is "instantiated":
my_big_struct a;
init_inner_struct(&a.inner_struct);
Here is an alternative example how you would do things like this with object-oriented design. Please note that this example uses runtime initialization.
mystruct.h
#ifndef MYSTRUCT_H
#define MYSTRUCT_H
typedef struct mystruct_t mystruct_t; // "opaque" type
const mystruct_t* mystruct_construct (void);
void mystruct_print (const mystruct_t* my);
void mystruct_destruct (const mystruct_t* my);
#endif
mystruct.c
#include "mystruct.h"
#include <stdlib.h>
#include <stdio.h>
struct mystruct_t // implementation of opaque type
{
int x; // private variable
int y; // private variable
};
const mystruct_t* mystruct_construct (void)
{
mystruct_t* my = malloc(sizeof(mystruct_t));
if(my == NULL)
{
; // error handling needs to be implemented
}
my->x = 1;
my->y = 2;
return my;
}
void mystruct_print (const mystruct_t* my)
{
printf("%d %d\n", my->x, my->y);
}
void mystruct_destruct (const mystruct_t* my)
{
free( (void*)my );
}
main.c
int main (void)
{
const mystruct_t* x = mystruct_construct();
mystruct_print(x);
mystruct_destruct(x);
return 0;
}
You don't necessarily need to use malloc, you can use a private, statically allocated memory pool as well.
Is there a clean way of casting a struct into an uint64_t or any other int, given that struct in <= to the sizeof int?
The only thing I can think of is only an 'ok' solution - to use unions. However I have never been fond of them.
Let me add a code snippet to clarify:
typedef struct {
uint8_t field: 5;
uint8_t field2: 4;
/* and so on... */
}some_struct_t;
some_struct_t some_struct;
//init struct here
uint32_t register;
Now how do i cast some_struct to capture its bits order in uint32_t register.
Hope that makes it a bit clearer.
I've just hit the same problem, and I solved it with a union like this:
typedef union {
struct {
uint8_t field: 5;
uint8_t field2: 4;
/* and so on... */
} fields;
uint32_t bits;
} some_struct_t;
/* cast from uint32_t x */
some_struct_t mystruct = { .bits = x };
/* cast to uint32_t */
uint32_t x = mystruct.bits;
HTH,
Alex
A non-portable solution:
struct smallst {
int a;
char b;
};
void make_uint64_t(struct smallst *ps, uint64_t *pi) {
memcpy(pi, ps, sizeof(struct smallst));
}
You may face problems if you, for example, pack the struct on a little-endian machine and unpack it on a big-endian machine.
you can use pointers and it will be easy
for example:
struct s {
int a:8;
int b:4;
int c:4;
int d:8;
int e:8; }* st;
st->b = 0x8;
st->c = 1;
int *struct_as_int = st;
hope it helps
You can cast object's pointer to desired type and then resolve it. I assume it can be a little bit slower than using unions or something else. But this does not require additional actions and can be used in place.
Short answer:
*(uint16_t *)&my_struct
Example:
#include <stdio.h>
#include <stdint.h>
typedef struct {
uint8_t field1;
uint8_t field2;
} MyStruct;
int main() {
MyStruct my_struct = {0xFA, 0x7D};
uint16_t num_my_struct = *(uint16_t *)&my_struct;
printf("%X \n", num_my_struct); // 7DFA
return 0;
}