I have set up structs in this way.
When I print the sizeof(DATA), I get 16. Why is it 16? I thought it would be 8 as 4 for idx, and 4 for the ptr.
I allocate memory for the STUDENT struct and STATS struct array of size 50. Have I allocated enough memory?
typedef struct {
int idNum;
int classNum;
} STATS;
typedef struct {
STATS * stats;
int currGrade;
}STUDENT;
typedef struct {
STUDENT * ptr;
int idx;
} DATA;
//student_main.c
void function1()
{
DATA d;
func(&d);
}
//student.c
void func(DATA * d)
{
Student * s = malloc(sizeof(STUDENT));
d->ptr = s;
d->ptr->currGrade = 1;
STATS * arr = malloc(sizeof(STATS)* 50);
d->ptr->stats = arr;
d->ptr->stats[0].idNum = 1;
d->ptr->stats[0].classNum = 1;
}
I have set up structs in this way. When I print the sizeof(DATA), I
get 16. Why is it 16? I thought it would be 8 as 4 for idx, and 4 for
the ptr.
Because compiler (may) add padding between/behind struct elements to satisfy alignment constraints. You can read something about data structure alignment here.
In your case of DATA, its 16B because (if your machine is x64)
typedef struct
{
STUDENT * ptr; // 8B pointer
int idx; // 4B int
// 4B padding
} DATA;
I allocate memory for the STUDENT struct and STATS struct array of
size 50. Have I allocated enough memory?
It depends on your needs. You have allocated enough space for 50 structures. Remember to always use sizeof(type) while allocating dynamical memory.
The compiler will pad structures, for example to allow faster access to subsequent elements in 64 bit architectures.
You shouldn't ever need to worry about the numeric value of the size of a struct, as the compiler handles it. Use it only for comparisons, and ignore the absolute value (unless your hobby is reverse engineering the compiler)
It can be 16 for one of two reasons - either You have 32 bit machine and the compiler adds some "space" in Your structure to make the operations faster. You can stop this behavior if You want your structures to be of the exact size, by adding __attribute__ ((__packed__)) to the struct definition. Or You have 64 bit machine with 64 bit pointers and integers. Or a mix of both.
You have allocated enough memory. Doing malloc(x * sizeof(struct xxx)) gives You the confidence.
I recommend reading this excellent article: The Lost Art of C Structure Packing
Related
I have looked around but have been unable to find a solution to what must be a well asked question.
Here is the code I have:
#include <stdlib.h>
struct my_struct {
int n;
char s[]
};
int main()
{
struct my_struct ms;
ms.s = malloc(sizeof(char*)*50);
}
and here is the error gcc gives me:
error: invalid use of flexible array member
I can get it to compile if i declare the declaration of s inside the struct to be
char* s
and this is probably a superior implementation (pointer arithmetic is faster than arrays, yes?)
but I thought in c a declaration of
char s[]
is the same as
char* s
The way you have it written now , used to be called the "struct hack", until C99 blessed it as a "flexible array member". The reason you're getting an error (probably anyway) is that it needs to be followed by a semicolon:
#include <stdlib.h>
struct my_struct {
int n;
char s[];
};
When you allocate space for this, you want to allocate the size of the struct plus the amount of space you want for the array:
struct my_struct *s = malloc(sizeof(struct my_struct) + 50);
In this case, the flexible array member is an array of char, and sizeof(char)==1, so you don't need to multiply by its size, but just like any other malloc you'd need to if it was an array of some other type:
struct dyn_array {
int size;
int data[];
};
struct dyn_array* my_array = malloc(sizeof(struct dyn_array) + 100 * sizeof(int));
Edit: This gives a different result from changing the member to a pointer. In that case, you (normally) need two separate allocations, one for the struct itself, and one for the "extra" data to be pointed to by the pointer. Using a flexible array member you can allocate all the data in a single block.
You need to decide what it is you are trying to do first.
If you want to have a struct with a pointer to an [independent] array inside, you have to declare it as
struct my_struct {
int n;
char *s;
};
In this case you can create the actual struct object in any way you please (like an automatic variable, for example)
struct my_struct ms;
and then allocate the memory for the array independently
ms.s = malloc(50 * sizeof *ms.s);
In fact, there's no general need to allocate the array memory dynamically
struct my_struct ms;
char s[50];
ms.s = s;
It all depends on what kind of lifetime you need from these objects. If your struct is automatic, then in most cases the array would also be automatic. If the struct object owns the array memory, there's simply no point in doing otherwise. If the struct itself is dynamic, then the array should also normally be dynamic.
Note that in this case you have two independent memory blocks: the struct and the array.
A completely different approach would be to use the "struct hack" idiom. In this case the array becomes an integral part of the struct. Both reside in a single block of memory. In C99 the struct would be declared as
struct my_struct {
int n;
char s[];
};
and to create an object you'd have to allocate the whole thing dynamically
struct my_struct *ms = malloc(sizeof *ms + 50 * sizeof *ms->s);
The size of memory block in this case is calculated to accommodate the struct members and the trailing array of run-time size.
Note that in this case you have no option to create such struct objects as static or automatic objects. Structs with flexible array members at the end can only be allocated dynamically in C.
Your assumption about pointer aritmetics being faster then arrays is absolutely incorrect. Arrays work through pointer arithmetics by definition, so they are basically the same. Moreover, a genuine array (not decayed to a pointer) is generally a bit faster than a pointer object. Pointer value has to be read from memory, while the array's location in memory is "known" (or "calculated") from the array object itself.
The use of an array of unspecified size is only allowed at the end of a structure, and only works in some compilers. It is a non-standard compiler extension. (Although I think I remember C++0x will be allowing this.)
The array will not be a separate allocation for from the structure though. So you need to allocate all of my_struct, not just the array part.
What I do is simply give the array a small but non-zero size. Usually 4 for character arrays and 2 for wchar_t arrays to preserve 32 bit alignment.
Then you can take the declared size of the array into account, when you do the allocating. I often don't on the theory that the slop is smaller than the granularity that the heap manager works in in any case.
Also, I think you should not be using sizeof(char*) in your allocation.
This is what I would do.
struct my_struct {
int nAllocated;
char s[4]; // waste 32 bits to guarantee alignment and room for a null-terminator
};
int main()
{
struct my_struct * pms;
int cb = sizeof(*pms) + sizeof(pms->s[0])*50;
pms = (struct my_struct*) malloc(cb);
pms->nAllocated = (cb - sizoef(*pms) + sizeof(pms->s)) / sizeof(pms->s[0]);
}
I suspect the compiler doesn't know how much space it will need to allocate for s[], should you choose to declare an automatic variable with it.
I concur with what Ben said, declare your struct
struct my_struct {
int n;
char s[1];
};
Also, to clarify his comment about storage, declaring char *s won't put the struct on the stack (since it is dynamically allocated) and allocate s in the heap, what it will do is interpret the first sizeof(char *) bytes of your array as a pointer, so you won't be operating on the data you think you are, and probably will be fatal.
It is vital to remember that although the operations on pointers and arrays may be implemented the same way, they are not the same thing.
Arrays will resolve to pointers, and here you must define s as char *s. The struct basically is a container, and must (IIRC) be fixed size, so having a dynamically sized array inside of it simply isn't possible. Since you're mallocing the memory anyway, this shouldn't make any difference in what you're after.
Basically you're saying, s will indicate a memory location. Note that you can still access this later using notation like s[0].
pointer arithmetic is faster than arrays, yes?
Not at all - they're actually the same. arrays translate to pointer arithmetics at compile-time.
char test[100];
test[40] = 12;
// translates to: (test now indicates the starting address of the array)
*(test+40) = 12;
Working code of storing array inside a structure in a c, and how to store value in the array elements Please leave comment if you have any doubts, i will clarify at my best
Structure Define:
struct process{
int process_id;
int tau;
double alpha;
int* process_time;
};
Memory Allocation for process structure:
struct process* process_mem_aloc = (struct process*) malloc(temp_number_of_process * sizeof(struct process));
Looping through multiple process and for each process updating process_time dyanamic array
int process_count = 0;
int tick_count = 0;
while(process_count < number_of_process){
//Memory allocation for each array of the process, will be containting size equal to number_of_ticks: can hold any value
(process_mem_aloc + process_count)->process_time = (int*) malloc(number_of_ticks* sizeof(int));
reading data from line by line from a file, storing into process_time array and then printing it from the stored value, next while loop is inside the process while loop
while(tick_count < number_of_ticks){
fgets(line, LINE_LENGTH, file);
*((process_mem_aloc + process_count)->process_time + tick_count) = convertToInteger(line);;
printf("tick_count : %d , number_of_ticks %d\n",tick_count,*((process_mem_aloc + process_count)->process_time + tick_count));
tick_count++;
}
tick_count = 0;
the code generated will be identical (array and ptr). Apart from the fact that the array one wont compile that is
and BTW - do it c++ and use vector
I am very new to C/C++, so I know that this question is probably trivial but I don't understand how to proceed. I have allocated blocks of memory that are 512 bytes each like so (Sector is a struct of size 512 bytes):
char* block = (char *) malloc (sizeof(Sector));
I have another struct that is 128 bytes in size:
typedef struct inode {
int fileSize;
int fileType;
int* blockPointer[30];
} inodeFile;
What I want to do is overlay this struct on the block. I need each block to contain 4 inode structs, but each struct may not have any values associated with it until later on in the program. So for example:
((*inodeFile) block)->fileSize = 10;
If I am understanding correctly, this is setting the first 4 bytes of the pointer block to fileSize. I would continue to do this for each field of the struct.
My question is, how can I do this for 4 different inodes? And since there are 4 different inodes, how can I return the values of each field for the different structs? It seems like simply saying block->fileSize wouldn't work because there can be up to four different file sizes.
You can use a union to overlay the blocks on the sectors. Because the fields are of int type or pointer or size 512 there shouldn't be an alignment problem so long as the natural size is 32-bit.
typedef struct {
int fileSize;
int fileType;
int* blockPointer[30];
} inode;
typedef union {
unsigned char bytes[512];
inode block[4];
} sector;
int main()
{
sector thisec;
thisec.bytes[511] = 0;
thisec.block[0].fileSize = 10;
return 0;
}
See the struct I used bellow. I wish to solve this problem in a portable way.
The code I used for finding the absolute address of the struct was: (char*)data - sizeof(struct block); (where data is the address to the data in the struct block). It did not work on this struct.
I made a test program seen bellow where the last assert fails.
If I change unsigned int free:1; to unsigned int free; both prints will print 12 and thus sizeof has given me the expected result.
Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct block {
size_t size;
struct block* next;
unsigned int free:1;
char data[];
};
int main(void)
{
struct block* avail;
struct block* b;
avail = malloc(sizeof(struct block) + 10);
printf("%zu \n", sizeof(struct block)); // prints 12
printf("%zu\n", avail->data - (char*)&avail->size); //prints 9
b = (struct block*)((char*)avail->data - 9);
assert(b == avail);
b = (struct block*)((char*)avail->data - sizeof(struct block));
assert(b == avail);
return 0;
}
EDIT: seems like I found the answer here on stack overflow:
how to get struct's start address from its member's address
It gives me correct absolute address.
The only guarantees you have regarding the layout (and size) of
struct block {
size_t size;
struct block* next;
unsigned int free:1;
char data[];
};
are that the addresses of the members (resp. the unit containign the bit-field) are increasing in the order of their listing, the members are suitably aligned for their types, and there's no padding at the start of the struct, so a pointer to the struct, suitably converted yields a pointer to its first member. The compiler is free to insert more padding between the members than needed for alignment.
However, usually, the padding inserted is only what is needed for alignment. Also the size and alignment requirements of size_t and struct block* are in most implementations the same, both 4 bytes on a 32 bit system and 8 bytes on a 64 bit system. Then the size of struct block is a multiple of k = sizeof(size_t), and the first k bytes are occupied by the size member, the next k bytes by the next pointer.
After that comes an unsigned bit-field of width 1. Such a small bit-field fits into any unit of storage, thus the implementation is free to choose a unit of storage of any size for it. Natural choices would be
one byte, since it's the smallest possible unit,
sizeof(int) bytes, since " A ‘‘plain’’ int object has the natural size suggested by the architecture of the execution environment".
Now, if the unit to contain the bit-field is chosen to have the size of one byte, as was the case for your implementation (and mine), the data member is typically placed directly after that, at an offset of 2*k+1 bytes, since the alignment of char is 1. If the unit for the bit-field is chosen to be int-sized, the offset of data will most likely be 2*k + sizeof(int), which on 32-bit systems is probably equal to sizeof(struct block), but not on 64-bit systems.
You can with very high probability bring the implementation to make
offsetof(struct block, data) == sizeof(struct block)
by inserting an unnamed bit-field of appropriate width (CHAR_BIT * sizeof(size_t) - 1) between free and data, but the only way that is portable and guaranteed to work is
struct block *b_addr = (struct block*)((char*)(avail->data) - offsetof(struct block, data));
as stated in Greg Hewgill's answer to the linked question.
sizeof(struct block) - sizeof(char*) should give you the size of the struct block, not including the data field. So, if you have a pointer to data, you should reach the beginning of the structure.
b = (struct block*)((char*)avail->data - (sizeof(struct block) - sizeof(char*));
assert(b == avail);
I have not tested it, though.
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);
I am using a library that has a function that takes an array of structs. That struct and function has the following layout:
struct TwoInt32s
{
int32_t a;
int32_t b;
};
void write(struct TwoInt32s *buffer, int len);
My initial tests suggest that an array of such structs has the same memory layout as an array of int32_t so I can do something like this:
int32_t *buffer = malloc(2 * len * sizeof(int32_t));
/* fill in the buffer */
write((struct TwoInt32s*)buffer, len);
However I'm wondering if this is universally true or not. Using an array of int32_t greatly simplifies my code.
EDIT: I forgot the sizeof
From what I read, C guarantees a few things about struct padding:
members will NOT be reordered
padding will only be added between members with different alignments or at the end of the struct
a pointer to a struct points to the same memory location as a pointer to its first member
each member is aligned in a manner appropriate for its type
there may be unnamed holes in the struct as necessary to achieve alignment
From this I can extrapolate that a and b have no padding between them. However it's possible that the struct will have padding at the end. I doubt this since it's word-aligned on both 32 and 64 bit systems. Does anyone have additional information on this?
The implementation is free to pad structs - there may be unused bytes in between a and b. It is guaranteed that the first member isn't offset from the beginning of the struct though.
Typically you manage such layout with a compiler-specific pragma, e.g:
#pragma pack(push)
#pragma pack(1)
struct TwoInt32s
{
int32_t a;
int32_t b;
};
#pragma pack(pop)
malloc allocates bytes. Why did you choose "2*len" ?
You could simply use "sizeof":
int32_t *buffer = malloc(len * sizeof(TwoInt32s));
/* fill in the buffer */
write((struct TwoInt32s*)buffer, len);
and as Erik mentioned, it would be a good practice to pack the struct.
It's safest to not cast, but convert -- i.e., create a new array and fill it with the values found in the struct, then kill the struct.
You could allocate structures but treat their members as a sort of virtual array:
struct TwoInt32s *buffer = malloc(len * sizeof *buffer);
#define BUFFER(i) (*((i)%2 ? &buffer[(i)/2].b : &buffer[(i)/2].a))
/* fill in the buffer, e.g. */
for (int i = 0; i < len * 2; i++)
BUFFER(i) = i;
Unfortunately, neither GCC nor Clang currently "get" this code.