I have a structure where the first element is tested and dependent on its value the rest of the structure will or will not be read. In the cases where the first element's value dictates that the rest of the structure will not be read, do I have to allocate enough memory for the entire structure or just the first element?
struct element
{
int x;
int y;
};
int foo(struct element* e)
{
if(e->x > 3)
return e->y;
return e->x;
}
in main:
int i = 0;
int z = foo((struct element*)&i);
I assume that if only allocating for the first element is valid, then I will have to be wary of anything that may attempt to copy the structure. i.e. passing the struct to a function.
don't force your information into structs where it's not needed: don't use the struct as the parameter of your function.
either pass the member of your struct to the function or use inheritance:
typedef struct {
int foo;
} BaseA;
typedef struct {
int bar;
} BaseB;
typedef struct {
BaseA a;
BaseB b;
} Derived;
void foo(BaseB* info) { ... }
...
Derived d;
foo(&d.b);
BaseB b;
foo(&b);
if you're just curious (and seriously don't use this): you may.
typedef struct {
int foo, goo, hoo, joo;
} A;
typedef struct {
int unused, goo;
} B;
int foo(A* a) { return a->goo; }
...
B b;
int goo = foo((A*)&b);
In general you'll have to allocate a block of memory at least as many bytes as are required to fully read the accessed member with the largest offset in your structure. In addition when writing to this block you have to make sure to use the same member offsets as in the original structure.
The point being, a structure is only a block of memory with different areas assigned different interpretations (int, char, other structs etc...) and accessing a member of a struct (after reordering and alignment) boils down to simply reading from or writing to a bit of memory.
I do not think the code as given is legitimate. To understand why, consider:
struct CHAR_AND_INT { unsigned char c; int i; }
CHAR_AND_INT *p;
A compiler would be entitled to assume that p->c will be word-aligned and have whatever padding would be necessary for p->i to also be word-aligned. On some processors, writing a byte may be slower than writing a word. For example, a byte-store instruction may require the processor to read a word from memory, update one byte within it, and write the whole thing back, while a word-store instruction could simply store the new data without having to read anything first. A compiler that knew that p->c would be word-aligned and padded could implement p->c = 12; by using a word store to write the value 12. Such behavior wouldn't yield desired results, however, if the byte following p->c wasn't padding but instead held useful data.
While I would not expect a compiler to impose "special" alignment or padding requirements on any part of the structure shown in the original question (beyond those which apply to int) I don't think anything in the standard would forbid a compiler from doing so.
You need to only check that the structure itself is allocated; not the members (in that case at least)
int foo(struct element* e)
{
if ( e != 0) // check that the e pointer is valid
{
if(e->x != 0) // here you only check to see if x is different than zero (values, not pointers)
return e->y;
}
return 0;
}
In you edited change, I think this is poor coding
int i = 0;
int z = foo((struct element*)&i);
In that case, i will be allocation on the stack, so its address is valid; and will be valid in foo; but since you cast it into something different, the members will be garbage (at best)
Why do you want to cast an int into a structure?
What is your intent?
If I have two structs:
typedef struct{
unsigned int time;
double rate;
}quote;
typedef struct{
unsigned int freeSlots;
unsigned int end;
unsigned int start;
unsigned int currSize;
unsigned int maxSize;
unsigned int startAt;
//unsigned int currIndex;
quote quoteBuffer[1];
}cbuf;
And I wanted to make a function that would modify the size of the quoteBuffer array inside cbuf, how exactly would I go about doing that? I have tried a few approaches but none have worked so far. I keep returning to the same format of:
quote *newQuoteBuffer = malloc(sizeof(quote) * newSize);
And if I already have an existing cbuf somewhere (for example, we will call it "a" where a is the pointer to the cbuf):
a->quoteBuffer = newQuoteBuffer;
But obviously this doesn't work. Any hints?
This:
quote quoteBuffer[1];
should be:
quote *quoteBuffer;
Then the assignment will work.
Dereferencing quote looks like this:
a->quoteBuffer->time;
If you later have multiple elements of quote allocated with malloc() you can access them like this:
a->quoteBuffer[i].time;
If you are not sure of how many elements will go into the quoteBuffer, maintain a linked list of the same. For that
quote *quoteBuffer;
And keep adding or removing the elements to/from the buffer as required.
I think you're missing the point of why someone would have the last element of a struct as a single element array. This is a trick that's used in old C code as a way to make the struct size variable length.
You can write code such as this:
Bitmapset *p = malloc(offsetof(Bitmapset, quoteBuffer) + n * sizeof(quote));
Then you write code like this:
p->quoteBuffer[0]
up to:
p->quoteBuffer[n-1]
You do not want to assign a pointer directly to quoteBuffer, as you guessed.
So, why would you want to declare quoteBuffer as:
quote quoteBuffer[1];
instead of
quote* quoteBuffer;
?
It's because you do not wanna to have a separate allocation for quoteBuffer. A single allocation can be used for the entire cbuf, including the inline quote array.
There are two approaches. One is to use a pointer in cbuf, as others have mentioned, by changing
quote quoteBuffer[1];
to
quote* quoteBuffer;
The other is to resize the cbuf:
#include <stddef.h> // for offsetof
struct cbuf* realloc_cbuf(struct cbuf* cbufp, size_t nquotes)
{
struct cbuf* new_cbufp = realloc(cbufp, offsetof(struct cbuf, quoteBuffer) + nquotes * sizeof *cbufp->quoteBuffer);
if (!new_cbufp)
{
// handle out of memory here. cbufp is still intact so free it if you don't need it.
}
return new_cbufp;
}
void elsewhere(void)
{
struct cbuf* acbuf = NULL;
acbuf = realloc_cbuf(1);
acbuf = realloc_cbuf(10);
// etc.
}
I have these three structures,
typedef struct serial_header {
int zigbeeMsgType;
int seqNumber;
int commandIdentifier;
int dest;
int src;
}serial_header_t;
typedef struct serial_packet {
serial_header_t header;
int data[];
} serial_packet_t;
and last one is
typedef struct readAttributePacket
{
int u8SourceEndPointId;
int u8DestinationEndPointId;
int u16ClusterId;
int bDirectionIsServerToClient;
int u8NumberOfAttributesInRequest;
int bIsManufacturerSpecific;
int u16ManufacturerCode;
int pu16AttributeRequestList[];
}readAttributePacket_t;
I am troubling with this code, i just want to cast the data[] array which reside in serial_packet_t into readAttributePacket_t structure.
I think the data[] should be
data[]={0x01,0x01,0x04,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
I need to cast those data to readAttributePacket_t structure. But this below code showing wrong.
void main()
{
int a[]= {0x32,0x00,0x31,0x69,0x69,0x00,0x00,0x01,0x01,0x04,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
int i;
readAttributePacket_t *p;
serial_packet_t *data;
data = (serial_packet_t*)&a;
for(i=0;i<20;i++){
printf(" %02x \n",a[i]);
}
p = (readAttributePacket_t *)&data->data;
printf("\nu8SourceEndPointId:%x \nu8DestinationEndPointId:%x \nu16ClusterId:%04x \nbDirectionIsServerToClient:%x \nu8NumberOfAttributesInRequest:%x \nbIsManufacturerSpecific:%x \nu16ManufacturerCode:%04x",p->u8SourceEndPointId,
p->u8DestinationEndPointId,
p->u16ClusterId,
p->bDirectionIsServerToClient,
p->u8NumberOfAttributesInRequest,
p->bIsManufacturerSpecific,
p->u16ManufacturerCode);
getch();
}
the output should be like
u8SourceEndPointId=01
u8DestinationEndPointId=01
u16ClusterId=0402
bDirectionIsServerToClient=00
u8NumberOfAttributesInRequest=02
bIsManufacturerSpecific=00
u16ManufacturerCode=0000
How could I get the pu16AttributeRequestList[] array into readAttributePacket_t structure, should like that,
pu16AttributeRequestList[0]=0000
pu16AttributeRequestList[1]=0001
You can't just cast an array to a structure because they're simply incompatible types. Due to memory alignment constraints, the compiler needs to insert padding between the fields of a structure, so the members are not located at the memory addresses you may expect. Solutions:
Portable but slower/harder to do manually (preferred): copy manually the fields of the structure to the array.
Shorter to write but GCC-specific: use the __attribute__((packed)) keyword to make GCC not introduce padding between struct fields.
Construct a union of 3 structs. all on equal memory space. then you dont even need to cast.
I think the only thing that you need to do in to remove the address operator from the casting statement.
data = (serial_packet_t*)a;
instead of
data = (serial_packet_t*)&a;
as far as I know, everything should work fine from here.
When should unions be used? Why do we need them?
Unions are often used to convert between the binary representations of integers and floats:
union
{
int i;
float f;
} u;
// Convert floating-point bits to integer:
u.f = 3.14159f;
printf("As integer: %08x\n", u.i);
Although this is technically undefined behavior according to the C standard (you're only supposed to read the field which was most recently written), it will act in a well-defined manner in virtually any compiler.
Unions are also sometimes used to implement pseudo-polymorphism in C, by giving a structure some tag indicating what type of object it contains, and then unioning the possible types together:
enum Type { INTS, FLOATS, DOUBLE };
struct S
{
Type s_type;
union
{
int s_ints[2];
float s_floats[2];
double s_double;
};
};
void do_something(struct S *s)
{
switch(s->s_type)
{
case INTS: // do something with s->s_ints
break;
case FLOATS: // do something with s->s_floats
break;
case DOUBLE: // do something with s->s_double
break;
}
}
This allows the size of struct S to be only 12 bytes, instead of 28.
Unions are particularly useful in Embedded programming or in situations where direct access to the hardware/memory is needed. Here is a trivial example:
typedef union
{
struct {
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
unsigned char byte4;
} bytes;
unsigned int dword;
} HW_Register;
HW_Register reg;
Then you can access the reg as follows:
reg.dword = 0x12345678;
reg.bytes.byte3 = 4;
Endianness (byte order) and processor architecture are of course important.
Another useful feature is the bit modifier:
typedef union
{
struct {
unsigned char b1:1;
unsigned char b2:1;
unsigned char b3:1;
unsigned char b4:1;
unsigned char reserved:4;
} bits;
unsigned char byte;
} HW_RegisterB;
HW_RegisterB reg;
With this code you can access directly a single bit in the register/memory address:
x = reg.bits.b2;
Low level system programming is a reasonable example.
IIRC, I've used unions to breakdown hardware registers into the component bits. So, you can access an 8-bit register (as it was, in the day I did this ;-) into the component bits.
(I forget the exact syntax but...) This structure would allow a control register to be accessed as a control_byte or via the individual bits. It would be important to ensure the bits map on to the correct register bits for a given endianness.
typedef union {
unsigned char control_byte;
struct {
unsigned int nibble : 4;
unsigned int nmi : 1;
unsigned int enabled : 1;
unsigned int fired : 1;
unsigned int control : 1;
};
} ControlRegister;
I've seen it in a couple of libraries as a replacement for object oriented inheritance.
E.g.
Connection
/ | \
Network USB VirtualConnection
If you want the Connection "class" to be either one of the above, you could write something like:
struct Connection
{
int type;
union
{
struct Network network;
struct USB usb;
struct Virtual virtual;
}
};
Example use in libinfinity: http://git.0x539.de/?p=infinote.git;a=blob;f=libinfinity/common/inf-session.c;h=3e887f0d63bd754c6b5ec232948027cbbf4d61fc;hb=HEAD#l74
Unions allow data members which are mutually exclusive to share the same memory. This is quite important when memory is more scarce, such as in embedded systems.
In the following example:
union {
int a;
int b;
int c;
} myUnion;
This union will take up the space of a single int, rather than 3 separate int values. If the user set the value of a, and then set the value of b, it would overwrite the value of a since they are both sharing the same memory location.
Lots of usages. Just do grep union /usr/include/* or in similar directories. Most of the cases the union is wrapped in a struct and one member of the struct tells which element in the union to access. For example checkout man elf for real life implementations.
This is the basic principle:
struct _mydata {
int which_one;
union _data {
int a;
float b;
char c;
} foo;
} bar;
switch (bar.which_one)
{
case INTEGER : /* access bar.foo.a;*/ break;
case FLOATING : /* access bar.foo.b;*/ break;
case CHARACTER: /* access bar.foo.c;*/ break;
}
Here's an example of a union from my own codebase (from memory and paraphrased so it may not be exact). It was used to store language elements in an interpreter I built. For example, the following code:
set a to b times 7.
consists of the following language elements:
symbol[set]
variable[a]
symbol[to]
variable[b]
symbol[times]
constant[7]
symbol[.]
Language elements were defines as '#define' values thus:
#define ELEM_SYM_SET 0
#define ELEM_SYM_TO 1
#define ELEM_SYM_TIMES 2
#define ELEM_SYM_FULLSTOP 3
#define ELEM_VARIABLE 100
#define ELEM_CONSTANT 101
and the following structure was used to store each element:
typedef struct {
int typ;
union {
char *str;
int val;
}
} tElem;
then the size of each element was the size of the maximum union (4 bytes for the typ and 4 bytes for the union, though those are typical values, the actual sizes depend on the implementation).
In order to create a "set" element, you would use:
tElem e;
e.typ = ELEM_SYM_SET;
In order to create a "variable[b]" element, you would use:
tElem e;
e.typ = ELEM_VARIABLE;
e.str = strdup ("b"); // make sure you free this later
In order to create a "constant[7]" element, you would use:
tElem e;
e.typ = ELEM_CONSTANT;
e.val = 7;
and you could easily expand it to include floats (float flt) or rationals (struct ratnl {int num; int denom;}) and other types.
The basic premise is that the str and val are not contiguous in memory, they actually overlap, so it's a way of getting a different view on the same block of memory, illustrated here, where the structure is based at memory location 0x1010 and integers and pointers are both 4 bytes:
+-----------+
0x1010 | |
0x1011 | typ |
0x1012 | |
0x1013 | |
+-----+-----+
0x1014 | | |
0x1015 | str | val |
0x1016 | | |
0x1017 | | |
+-----+-----+
If it were just in a structure, it would look like this:
+-------+
0x1010 | |
0x1011 | typ |
0x1012 | |
0x1013 | |
+-------+
0x1014 | |
0x1015 | str |
0x1016 | |
0x1017 | |
+-------+
0x1018 | |
0x1019 | val |
0x101A | |
0x101B | |
+-------+
I'd say it makes it easier to reuse memory that might be used in different ways, i.e. saving memory. E.g. you'd like to do some "variant" struct that's able to save a short string as well as a number:
struct variant {
int type;
double number;
char *string;
};
In a 32 bit system this would result in at least 96 bits or 12 bytes being used for each instance of variant.
Using an union you can reduce the size down to 64 bits or 8 bytes:
struct variant {
int type;
union {
double number;
char *string;
} value;
};
You're able to save even more if you'd like to add more different variable types etc. It might be true, that you can do similar things casting a void pointer - but the union makes it a lot more accessible as well as type safe. Such savings don't sound massive, but you're saving one third of the memory used for all instances of this struct.
Many of these answers deal with casting from one type to another. I get the most use from unions with the same types just more of them (ie when parsing a serial data stream). They allow the parsing / construction of a framed packet to become trivial.
typedef union
{
UINT8 buffer[PACKET_SIZE]; // Where the packet size is large enough for
// the entire set of fields (including the payload)
struct
{
UINT8 size;
UINT8 cmd;
UINT8 payload[PAYLOAD_SIZE];
UINT8 crc;
} fields;
}PACKET_T;
// This should be called every time a new byte of data is ready
// and point to the packet's buffer:
// packet_builder(packet.buffer, new_data);
void packet_builder(UINT8* buffer, UINT8 data)
{
static UINT8 received_bytes = 0;
// All range checking etc removed for brevity
buffer[received_bytes] = data;
received_bytes++;
// Using the struc only way adds lots of logic that relates "byte 0" to size
// "byte 1" to cmd, etc...
}
void packet_handler(PACKET_T* packet)
{
// Process the fields in a readable manner
if(packet->fields.size > TOO_BIG)
{
// handle error...
}
if(packet->fields.cmd == CMD_X)
{
// do stuff..
}
}
Edit
The comment about endianness and struct padding are valid, and great, concerns. I have used this body of code almost entirely in embedded software, most of which I had control of both ends of the pipe.
It's difficult to think of a specific occasion when you'd need this type of flexible structure, perhaps in a message protocol where you would be sending different sizes of messages, but even then there are probably better and more programmer friendly alternatives.
Unions are a bit like variant types in other languages - they can only hold one thing at a time, but that thing could be an int, a float etc. depending on how you declare it.
For example:
typedef union MyUnion MYUNION;
union MyUnion
{
int MyInt;
float MyFloat;
};
MyUnion will only contain an int OR a float, depending on which you most recently set. So doing this:
MYUNION u;
u.MyInt = 10;
u now holds an int equal to 10;
u.MyFloat = 1.0;
u now holds a float equal to 1.0. It no longer holds an int. Obviously now if you try and do printf("MyInt=%d", u.MyInt); then you're probably going to get an error, though I'm unsure of the specific behaviour.
The size of the union is dictated by the size of its largest field, in this case the float.
Unions are used when you want to model structs defined by hardware, devices or network protocols, or when you're creating a large number of objects and want to save space. You really don't need them 95% of the time though, stick with easy-to-debug code.
In school, I used unions like this:
typedef union
{
unsigned char color[4];
int new_color;
} u_color;
I used it to handle colors more easily, instead of using >> and << operators, I just had to go through the different index of my char array.
union are used to save memory, especially used on devices with limited memory where memory is important.
Exp:
union _Union{
int a;
double b;
char c;
};
For example,let's say we need the above 3 data types(int,double,char) in a system where memory is limited.If we don't use "union",we need to define these 3 data types. In this case sizeof(a) + sizeof(b) + sizeof(c) memory space will be allocated.But if we use onion,only one memory space will be allocated according to the largest data t ype in these 3 data types.Because all variables in union structure will use the same memory space. Hence the memory space allocated accroding to the largest data type will be common space for all variables.
For example:
union _Union{
int a;
double b;
char c;
};
int main() {
union _Union uni;
uni.a = 44;
uni.b = 144.5;
printf("a:%d\n",uni.a);
printf("b:%lf\n",uni.b);
return 0;
}
Output is:
a: 0
and b:144.500000
Why a is zero?. Because union structure has only one memory area and all data structures use it in common. So the last assigned value overwrites the old one.
One more example:
union _Union{
char name[15];
int id;
};
int main(){
union _Union uni;
char choice;
printf("YOu can enter name or id value.");
printf("Do you want to enter the name(y or n):");
scanf("%c",&choice);
if(choice == 'Y' || choice == 'y'){
printf("Enter name:");
scanf("%s",uni.name);
printf("\nName:%s",uni.name);
}else{
printf("Enter Id:");
scanf("%d",&uni.id);
printf("\nId:%d",uni.id);
}
return 0;
}
Note:Size of the union is the size of its largest field because sufficient number of bytes must be reserved to store the larges sized field.
In early versions of C, all structure declarations would share a common set of fields. Given:
struct x {int x_mode; int q; float x_f};
struct y {int y_mode; int q; int y_l};
struct z {int z_mode; char name[20];};
a compiler would essentially produce a table of structures' sizes (and possibly alignments), and a separate table of structures' members' names, types, and offsets. The compiler didn't keep track of which members belonged to which structures, and would allow two structures to have a member with the same name only if the type and offset matched (as with member q of struct x and struct y). If p was a pointer to any structure type, p->q would add the offset of "q" to pointer p and fetch an "int" from the resulting address.
Given the above semantics, it was possible to write a function that could perform some useful operations on multiple kinds of structure interchangeably, provided that all the fields used by the function lined up with useful fields within the structures in question. This was a useful feature, and changing C to validate members used for structure access against the types of the structures in question would have meant losing it in the absence of a means of having a structure that can contain multiple named fields at the same address. Adding "union" types to C helped fill that gap somewhat (though not, IMHO, as well as it should have been).
An essential part of unions' ability to fill that gap was the fact that a pointer to a union member could be converted into a pointer to any union containing that member, and a pointer to any union could be converted to a pointer to any member. While the C89 Standard didn't expressly say that casting a T* directly to a U* was equivalent to casting it to a pointer to any union type containing both T and U, and then casting that to U*, no defined behavior of the latter cast sequence would be affected by the union type used, and the Standard didn't specify any contrary semantics for a direct cast from T to U. Further, in cases where a function received a pointer of unknown origin, the behavior of writing an object via T*, converting the T* to a U*, and then reading the object via U* would be equivalent to writing a union via member of type T and reading as type U, which would be standard-defined in a few cases (e.g. when accessing Common Initial Sequence members) and Implementation-Defined (rather than Undefined) for the rest. While it was rare for programs to exploit the CIS guarantees with actual objects of union type, it was far more common to exploit the fact that pointers to objects of unknown origin had to behave like pointers to union members and have the behavioral guarantees associated therewith.
Unions are great. One clever use of unions I've seen is to use them when defining an event. For example, you might decide that an event is 32 bits.
Now, within that 32 bits, you might like to designate the first 8 bits as for an identifier of the sender of the event... Sometimes you deal with the event as a whole, sometimes you dissect it and compare it's components. unions give you the flexibility to do both.
union Event
{
unsigned long eventCode;
unsigned char eventParts[4];
};
What about VARIANT that is used in COM interfaces? It has two fields - "type" and a union holding an actual value that is treated depending on "type" field.
I used union when I was coding for embedded devices. I have C int that is 16 bit long. And I need to retrieve the higher 8 bits and the lower 8 bits when I need to read from/store to EEPROM. So I used this way:
union data {
int data;
struct {
unsigned char higher;
unsigned char lower;
} parts;
};
It doesn't require shifting so the code is easier to read.
On the other hand, I saw some old C++ stl code that used union for stl allocator. If you are interested, you can read the sgi stl source code. Here is a piece of it:
union _Obj {
union _Obj* _M_free_list_link;
char _M_client_data[1]; /* The client sees this. */
};
A file containing different record types.
A network interface containing different request types.
Take a look at this: X.25 buffer command handling
One of the many possible X.25 commands is received into a buffer and handled in place by using a UNION of all the possible structures.
A simple and very usefull example, is....
Imagine:
you have a uint32_t array[2] and want to access the 3rd and 4th Byte of the Byte chain.
you could do *((uint16_t*) &array[1]).
But this sadly breaks the strict aliasing rules!
But known compilers allow you to do the following :
union un
{
uint16_t array16[4];
uint32_t array32[2];
}
technically this is still a violation of the rules. but all known standards support this usage.
Use a union when you have some function where you return a value that can be different depending on what the function did.