Structures, internal structures and size in C - c

I'm programming for embedded, resource constrained devices in C.
I have a structure, like this:
typedef struct UjThread{
struct{
UInt32 runInstr;
UInt8* mailbox;
}appBucket;
struct{
UInt32 appId;
UInt32 numInstr;
UInt32 allocMem;
UInt32 eepromStartAddr;
}appContract;
UInt16 spBase; //we use an empty ascending stack
UInt16 spLimit; //also used for "isPtr"
UInt16 localsBase;
UInt32 stack[];
}UjThread;
I start a thread per object and allocate the needed memory (92 bytes for this structure, but I haven't shown all fields).
However, some objects won't use the internal appContract and appBucket structures but memory for those structures will still be allocated.
Is there a way to avoid this? To designate internal structures as optional or perhaps extract the size of those internal structures and subtract it from the memory allocation?
I could make two separate structures, one per type of object, but I'd prefer not to since I'd have to adjust my code everywhere to work with the two types of threads.

Besides the obvious - using two structs, I see only two other possibilities.
Either use a pointer to a separately allocated appContract, or if some of the data you need is mutually exclusive, use a union.

Consider this implementation of single inheritance that works in C.
Define a base struct that contains all the elements common to both objects. Notice that I've changed the type of the stack member to a pointer because that's going to have to be a separate allocation in this design.
typedef struct ThreadBase{
UInt16 spBase; //we use an empty ascending stack
UInt16 spLimit; //also used for "isPtr"
UInt16 localsBase;
UInt32 *stack;
}ThreadBase;
Then declare another struct that contains the base object as the first member and appends the extra stuff.
typedef struct ThreadExtra{
ThreadBase base;
struct{
UInt32 runInstr;
UInt8* mailbox;
}appBucket;
struct{
UInt32 appId;
UInt32 numInstr;
UInt32 allocMem;
UInt32 eepromStartAddr;
}appContract;
}ThreadExtra;
Now you can define a ThreadBase object for threads that only need the base stuff. And you can define a ThreadExtra object for the threads that need more. But you can cast the ThreadExtra object to ThreadBase because ThreadBase is the first member of ThreadExtra. So in general purpose code that doesn't deal with the ThreadExtra elements you can treat all the Thread objects as if they are ThreadBase objects.

If your optional fields are at the beginning of your struct, you can adjust the address of an allocated object, so the optional fields reside in unallocated memory. Use the offsetof macro to determine where the mandatory data starts:
offsetof(UjThread, spBase) // in bytes
Adjust the allocation size by this amount:
UjThread *newThread;
if (NoOptionalFields())
{
size_t sizeReduce = offsetof(UjThread, spBase);
size_t size = sizeof(UjThread) - sizeReduce;
newThread = (void*)((char*)malloc(size) - sizeReduce);
}
else
{
newThread = malloc(sizeof(UjThread));
}
To free the memory, don't forget to adjust the pointer back:
if (NoOptionalFields())
{
size_t sizeReduce = offsetof(UjThread, spBase);
free((char*)newThread + sizeReduce);
}
else
{
free(newThread);
}
BTW since you have a "flexible array member" in your struct, the actual size calculation is more complicated than in my example. But you get the idea - just subtract the size of the optional fields from both the allocation size and the resulting pointer.

If the stack had a fixed size, you could use the idiomatic C-style single inheritance:
typedef struct {
int a;
} Base;
typedef struct {
Base base;
int b;
} Derived;
void useBase(Base *);
void test(void) {
Base b;
Derived d;
useBase(&b);
useBase(&d.base); // variant 1
useBase((Base*)&d); // variant 2
}
Alas, the stack doesn't have a fixed size, so the somewhat idiomatic if unnecessarily shaky variant 2 won't work, but variant 1 will:
typedef struct {
int a[];
} Small;
typedef struct {
int b;
Small small;
} Large;
void useBase(Base *);
void test(void) {
Small s;
Large l;
useBase(&s);
useBase(&l.small);
}

Related

"Marking" Pointers in C with "attributes"

I have a huge buffer allocated with malloc on the heap, i want to write a custom allocator to allocate space from that buffer.
My question is now, if there's a way to "mark" some regions as "allocatable", "writable" and "reserved" in that buffer, like in Kernel Development.
An example, we've a buffer with 6 elements, how could i mark elements 2-5 as "reserved"?
[0][1][2][3][4][5]
Could it be possible with flags, a Bit Manipulation or something?
Or could i mark the pointer?
You could use something as simple as an array of struct (or a linked list) that includes a flag in each instance that you can set to indicate allocation allowed, or not.
For example, using a flag and ambiguous typing (void *):
typedef struct {
BOOL alloc; //set TRUE to allow or FALSE to disallow further allocation
void *space;
//other members
}BUF;
Create an array of BUF, and set the alloc member to TRUE or FALSE to set an instance be no longer accessible to changing its memory. Of course this would occur after initial memory had been allocated during initialization.
Or another possibility using enum of types, in conjunction with a union:
typedef enum {
_INT,
_UINT,
_CHAR,
_UCHAR,
... //other types
}TYPE;
typedef struct {
BOOL alloc; //set to allow or disallow further allocation
TYPE type; //flag to track type being used in instance
union {
char *cMem;
unsigned char *ucMem;
int *iMem;
unsigned int *uiMem;
... // other members
char *space;
}BUF;
Convert number of buffers in to bit array of unsigned int and use index of memory to mark it.
E.g.: unsigned int allocatable [((x) +31)>>5];
similar for writable and reserved.

Structure definition in C

I want to define a structure on the following way:
typedef struct Info_s
{
uint8 Size;
uint8 Address;
uint8 Pattern[Size];
}Info_t;
As you can notice the size of the array Pattern is "Size" which is declared first in the same structure.
Is that correct?
An array declared as a struct field must either have an integer constant expression as its size or be a flexible array member with no size (uint8 Pattern[];). Your variant is neither.
If the array size in your case is a run-time value, you have two choices
Flexible array member uint8 Pattern[];, which will result in a "flat" struct. The proper amount of memory to accommodate the entire struct with the array of desired length will have to be allocated with malloc manually.
Pointer member uint8 *Pattern;, in which case your struct will become two-leveled. Memory for the struct itself and memory for the array will generally become two separate memory blocks allocated independently.
A flexible array member is typically a better idea (and matches your apparent original intent), unless you have some other requirements that would preclude that aproach.
You can't do that. That is violating the rule. Compile the code and you will know it clearly.
Rather keep a uint8* and then allocate to it memory (using malloc,realloc etc) based on the value of Size.
And now if you increase or decraese the value Size as per that reallocate your memory.
Yes with this, you have to free the dynamically allocated memory when you are done working with it.
Just remove the array size Size in the declaration of Pattern and you will get a valid declaration of a structure with a flexible array member.:)
typedef struct Info_s
{
uint8 Size;
uint8 Address;
uint8 Pattern[];
}Info_t;
Go with
uint8* Pattern;
and use malloc to allocate its size once Size is known.
If you want to dynamically allocate memory to the structure, you can do it in following way :
struct Info_s
{
uint8 Address;
uint8 Pattern[Size];
};
int main()
{
struct Info_s *no;
int i, noOfRecords;
printf("Enter no: ");
scanf("%d", &noOfRecords);
no=(struct Info_s*) malloc (noOfRecords * sizeof(struct course));
for(i=0;i<noOfRecords;++i)
{
scanf(...);
}
.
.
.
return 0;
}
You can also refer https://www.programiz.com/c-programming/examples/structure-dynamic-memory-allocation for more information.

Setting the size of an array inside a struct with a value of another value within the same struct, in C

struct {
uint16 msg_length;
uint8 msg_type;
ProtocolVersion version;
uint16 cipher_spec_length;
uint16 session_id_length;
uint16 challenge_length;
V2CipherSpec cipher_specs[V2ClientHello.cipher_spec_length];
opaque session_id[V2ClientHello.session_id_length];
opaque challenge[V2ClientHello.challenge_length;
} V2ClientHello;
Is it possible to do something similar to the above (https://www.rfc-editor.org/rfc/rfc5246)? If so how do I go about coding this inside C?
To be more specific this line in the struct:
V2CipherSpec cipher_specs[V2ClientHello.cipher_spec_length];
Uses:
> V2ClientHello.cipher_spec_length
Which is defined in the same struct, to set the length of the array.
C does not support dynamic-sized arrays. To achieve your goal, you can use a pointer of type V2CipherSpec as structure variable and allocate memory at a later stage using the V2ClientHello.cipher_spec_length value.
Absolutely not. C does not have dynamic-size arrays. Instead, we can rely on tricks like this:
struct {
uint16 msg_length;
uint8 msg_type;
ProtocolVersion version;
uint16 cipher_spec_length;
uint16 session_id_length;
uint16 challenge_length;
char extra[0]; // or 1 if your compiler hates this
} V2ClientHello;
Then, do not create instances of this struct directly, but rather via malloc():
struct V2ClientHello* hello = malloc(sizeof(V2ClientHello) +
len1*sizeof(V2CipherSpec) + len2 + len3);
Now you have a dynamically-allocated structure of the size you need. You can make accessor functions to get the "extra" fields:
V2CipherSpec* get_spec(V2ClientHello* hello, int idx) {
assert(idx < hello->cipher_spec_length);
return ((V2CipherSpec*)&hello->extra)[idx];
}
And of course you can wrap up the malloc() call inside a create routine which takes the sizes of all three dynamic parts and does everything in one place for robustness.
The shown code from the RFC is pseudo code, you can not implement it as shown.
You need to allocate these arrays manually depending on V2ClientHello.cipher_spec_length and the other length specification fields, once their values are known.
Value of "V2ClientHello.cipher_spec_length" is not available at compile time. You can not specify the size of an array at run time, instead use:
V2CipherSpec *cipher_specs;
in struct and use malloc or calloc to allocate a block of memory at run time.
V2ClientHello.cipher_specs = (V2CipherSpec *)malloc(V2ClientHello.cipher_spec_length);

Generic static Vector data type in C with data segment memory

Is it possible to create a generic Vector like data structure in C, with out using heap. Basically I need a array data type but a more generalized version on if it.
typedef struct {
/* some data types*/
}TYPE1;
typedef struct {
/* some data types*/
}TYPE2;
typedef struct _GCACHE_T
{
const int element_size;
const int count;
struct _ELEMENT {
UBYTE data[element_size];
BOOLEAN is_valid;
}element[count];
}GCACHE_T;
GCACHE_T f_cache1 = {sizeof(TYPE1), 15, {0} };
GCACHE_T f_cache2 = {sizeof(TYPE2), 10, {0} };
The above code will not compile but I have provided it for a better clarity on my requirement.
This would have been easy implemted provided heap memory was allowed to use. Since the code is meant for small micros heap memory usage is not allowed.
I could have used right away, but just checking if it can be done in a generic way.
TYPE1 f_cache1[15];
TYPE2 f_cache2[10];
The Vector will not grow in size. I could have also used a union but there is a memory trade off so not willing to use it.
Such parametric (template, generic) types are not supported by C. You can take an approach similar to the one used by the BSD socket subsystem. There different network addresses (e.g. IP address and TCP/UDP port number) are stored in structures of varying size (depending on the address family, e.g. IPv4 structures are shorter than IPv6 ones) but with similar layout in the beginning. Whenever an address is required, a pointer to the generic struct sockaddr type is passed instead and the correct structure type is inferred from the address family of the socket.
C supports the so-called flexible array members, but it cannot be simply applied to your case because not only is the number of struct _ELEMENT entries different, but the size of those elements could differ depending on the value of element_size. This makes it hard to compute the address of cache.element[i].data[j] in a portable way whithout refering to the actual type. What you can do is put an additional field in the beginning of the GCACHE_T type that helps you identify the true size of struct _ELEMENT:
typedef struct _GCACHE_T
{
int element_size;
int count;
size_t element_stride;
struct _ELEMENT {
BOOLEAN is_valid;
UBYTE data[];
} element[];
} GCACHE_T;
element_stride keeps the size of the concrete element type (including any padding). Note that is_valid is moved before data[] as C allows only the last element of a structure to be a flexible one.
You would then create specific types, e.g.
typedef struct _GCACHE_TYPE1_15_T
{
int element_size;
int count;
size_t element_stride;
struct {
BOOLEAN is_valid;
UBYTE data[sizeof(TYPE1)];
} element[15];
} GCACHE_TYPE1_15_T;
GCACHE_TYPE1_15_T f_cache1 = {
sizeof(TYPE1),
15,
// An awful hack to obtain the size of a structure member
sizeof(((GCACHE_TYPE1_15_T *)0)->element[0])
};
do_something((GCACHE_T *)&f_cache1);
Macros would come handy if you need to declare many different cache types. Now in do_something() you can compute the address of f_cache1.element[i].data[j] because you know the offset of the data field inside struct _ELEMENT and you can compute the offset of element[i] because the size of a single element is stored in the element_stride field.
Yeah, I know, it is a real pain... And I am not sure how much of the pointer arithmetic required works on a Harvard architecture device like PIC.

C struct size alignment

I want the size of a C struct to be multiple of 16 bytes (16B/32B/48B/..).
It does not matter which size it gets to; it only needs to be multiple of 16 bytes.
How could I enforce the compiler to do that?
For Microsoft Visual C++:
#pragma pack(push, 16)
struct _some_struct
{
...
}
#pragma pack(pop)
For GCC:
struct _some_struct { ... } __attribute__ ((aligned (16)));
Example:
#include <stdio.h>
struct test_t {
int x;
int y;
} __attribute__((aligned(16)));
int main()
{
printf("%lu\n", sizeof(struct test_t));
return 0;
}
compiled with gcc -o main main.c will output 16. The same goes for other compilers.
The size of a C struct will depend on the members of the struct, their types and how many of them there are. There is really no standard way to force the compiler to make structs to be a multiple of some size. Some compilers provide a pragma that will allow you to set the alignment boundary however that is really a different thing. And there may be some that would have such a setting or provide such a pragma.
However if you insist on this one method would be to do memory allocation of the struct and to force the memory allocation to round up to the next 16 byte size.
So if you had a struct like this.
struct _simpleStruct {
int iValueA;
int iValueB;
};
Then you could do something like the following.
{
struct _simpleStruct *pStruct = 0;
pStruct = malloc ((sizeof(*pStruct)/16 + 1)*16);
// use the pStruct for whatever
free(pStruct);
}
What this would do is to push the size up to the next 16 byte size so far as you were concerned. However what the memory allocator does may or may not be to give you a block that is actually that size. The block of memory may actually be larger than your request.
If you are going to do something special with this, for instance lets say that you are going to write this struct to a file and you want to know the block size then you would have to do the same calculation used in the malloc() rather than using the sizeof() operator to calculate the size of the struct.
So the next thing would be to write your own sizeof() operator using a macro such as.
#define SIZEOF16(x) ((sizeof(x)/16 + 1) * 16)
As far as I know there is no dependable method for pulling the size of an allocated block from a pointer. Normally a pointer will have a memory allocation block that is used by the memory heap management functions that will contain various memory management information such as the allocated block size which may actually be larger than the requested amount of memory. However the format for this block and where it is located relative to the actual memory address provided will depend on the C compiler's run time.
This depends entirely on the compiler and other tools since alignment is not specified that deeply in the ISO C standard (it specifies that alignment may happen at the compilers behest but does not go into detail as to how to enforce it).
You'll need to look into the implementation-specific stuff for your compiler toolchain. It may provide a #pragma pack (or align or some other thing) that you can add to your structure defininition.
It may also provide this as a language extension. For example, gcc allows you to add attributes to a definition, one of which controls alignment:
struct mystruct { int val[7]; } __attribute__ ((aligned (16)));
You could perhaps do a double struct, wrapping your actual struct in a second one that can add padding:
struct payload {
int a; /*Your actual fields. */
float b;
char c;
double d;
};
struct payload_padded {
struct payload p;
char padding[16 * ((sizeof (struct payload) + 15) / 16)];
};
Then you can work with the padded struct:
struct payload_padded a;
a.p.d = 43.3;
Of course, you can make use of the fact that the first member of a structure starts 0 bytes from where the structure starts, and treat a pointer to struct payload_padded as if it's a pointer to a struct payload (because it is):
float d_plus_2(const struct payload *p)
{
return p->d + 2;
}
/* ... */
struct payload_padded b;
const double dp2 = d_plus_2((struct payload *) &b);

Resources