Why is the size of same struct different? [duplicate] - c

This question already has answers here:
Structure padding and packing
(11 answers)
Why isn't sizeof for a struct equal to the sum of sizeof of each member?
(13 answers)
Closed 3 months ago.
This post was edited and submitted for review 3 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Why is the size of these two struct different depending on #include <stdbool.h> vs. typedef enum { false, true } bool; ?
#include <stdio.h>
#include <stdbool.h>
//typedef enum { false, true } bool;
struct x {
bool a;
int b;
char c;
};
struct y {
bool b;
char a;
int c;
};
int main(void) {
struct x x;
struct y y;
printf("Size of struct x:\t %zu\n", sizeof(x));
printf("Size of struct y:\t %zu", sizeof(y));
return 0;
}
With #include <stdio.h> the results on my machine (Mac, Intel):
Size of struct x: 12
Size of struct y: 8
I assume the size difference (i.e. 8 and 12) here is due to C utilizing some kind of memory structure padding.
With typedef enum { false, true } bool; the result:
Size of struct x: 12
Size of struct y: 12
Note: The question is not about structured padding (read more about that here and here), but why #include <stdbool.h> vs.
typedef enum { false, true } bool; gives different results to the same lines of code.

Related

Issue with structures in C language

I have an issue with structures in C, I don't know exactly what is happening. Could you explain me where I am wrong and correct me?
I declared a structure like below
typedef struct
{
Fuel_Intrl_IDs Curr_Bar; /*enum variable*/
uint16_t Pres_Value;
uint16_t Prev_Value;
}Bar_Dync_Data;
I assigned values for all the 3 variables, then when I am accessing data in these variables, value in "Prev_value is always returning "0".
On reassigning the structure as follows, everything is working fine:
typedef struct
{
uint16_t Pres_Value;
Fuel_Intrl_IDs Curr_Bar; /*enum variable*/
uint16_t Prev_Value;
}Bar_Dync_Data;
Can you explain what is happening here?
Code for reproducing
#include <stdio.h>
#include <stdlib.h>
#include <stdint-gcc.h>
typedef enum /*Fuel Internal IDs*/
{
Fuel_Intrl_ID_End
}Fuel_Intrl_IDs;
typedef struct /*Structure for Storing BAR ON/OFF Values*/
{
Fuel_Intrl_IDs Curr_Bar;
uint16_t Pres_Value;
uint16_t Prev_Value;
}Bar_Dync_Data;
Bar_Dync_Data FBar_Dync_Data;
int main()
{
printf("Hello world!\n");
FBar_Dync_Data.Prev_Value = 255;
while(1)
{
printf("\n Enter Pres value ");
scanf("%d",&FBar_Dync_Data.Pres_Value);
printf("\n Present value: %d",FBar_Dync_Data.Pres_Value);
printf("\n Previous value: %d",FBar_Dync_Data.Prev_Value);
FBar_Dync_Data.Prev_Value = FBar_Dync_Data.Pres_Value;
// getch();
}
return 0;
}

Find offset in struct [duplicate]

This question already has answers here:
How can I get/set a struct member by offset
(6 answers)
Closed 2 years ago.
I have struct in c
struct Book {
char title[50];
char author[50];
char subject[100];
int book_id;
};
struct Book * book;
I can access the integer book_id like book->book_id
But how can I access to book_id by offset? How can I calc (in c code) the offset of specific element in struct and access like book+X
#define offset(type, member) ((size_t)&(((type *)0) -> member))
#define ACCESS(object, type, offset) (type *)(((char *)&(object)) + (offset))
typedef struct
{
int a,b,c;
}t;
int main(void)
{
t s = {1,2,3};
printf("%zu\n", offset(t,b));
printf("%d\n", *ACCESS(s, int, offset(t,b)));
}

Realloc keeps returning NULL if reallocating structs [duplicate]

This question already has answers here:
Assignment of function parameter has no effect outside the function
(2 answers)
How do I modify a pointer that has been passed into a function in C?
(7 answers)
Closed 2 years ago.
Don't mind my code writing style. I specifically created this for testing purposes...
Now to the problem:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define EMB 31
#define NAME_MAX 50
struct TRIP {
char TRIP_NAME[EMB];
int TRIP_TIME;
};
struct DATE {
int day;
int month;
int year;
};
struct TRIP_INFORMATION {
char TRIP_NUMBER[EMB];
char EMBARKATION_POINT[EMB];
char SPECIFIC_DROPOFFPOINT[EMB];
char EXIT_DROPOFFPOINT[EMB];
struct DATE TRIP_DATE;
struct TRIP SPECIFIC_TRIP;
};
struct EMBARKATION_CARD{
//struct DATE TRIP_DATE;
char NAME[NAME_MAX];
int ID_NUMBER;
int PRIORITY_NUMBER;
//int TRIP_TIME;
//char EMBARKATION_POINT[EMB];
//char DROPOFFPOINT[EMB];
struct TRIP_INFORMATION TRIP_INFORMATION;
};
This is for the reference of declaration.
int BeginEmbarkationProcess(int *PASSENGER_COUNT, struct EMBARKATION_CARD * PASSENGER_TO_SAVE, int curr_day, int curr_month, int curr_year){
//struct EMBARKATION_CARD * P;
if(*PASSENGER_COUNT>1){
PASSENGER_TO_SAVE = realloc(PASSENGER_TO_SAVE, *PASSENGER_COUNT * sizeof(struct EMBARKATION_CARD));
if(PASSENGER_TO_SAVE == NULL){
puts("PASSENGER_TO_SAVE VARIABLE = HAS NOT ALLOCATED MEMORY");
return -1;
}
}
if(PASSENGER_TO_SAVE==NULL){
puts("PASSENGER TO SAVE POINTER HAS UNABLE TO ALLOCATE MEMORY");
return -1;
}
int x = 0;
for(x=0;x<*PASSENGER_COUNT;x++){
((PASSENGER_TO_SAVE+x))->ID_NUMBER = (x+1)*30;
((PASSENGER_TO_SAVE+x))->PRIORITY_NUMBER = (x+1)*17;
}
for(x=0;x<*PASSENGER_COUNT;x++){
printf("%d %d\n", (PASSENGER_TO_SAVE+x)->ID_NUMBER , (PASSENGER_TO_SAVE+x)->PRIORITY_NUMBER);
}
*PASSENGER_COUNT = *PASSENGER_COUNT + 1;
int r;
printf("ENTER -1 TO TERMINATE THIS LOOP\n");
scanf("%d", &r);
return r;
}
int main(){
//doIt();
struct EMBARKATION_CARD* E = malloc(sizeof(struct EMBARKATION_CARD));
int ct = 1;
int s = BeginEmbarkationProcess(&ct, E, 3, 3, 2020);
while(s!=-1){
s = BeginEmbarkationProcess(&ct, E, 3, 3, 2020);
}
return s;
}
Since I copy pasted this (and removed some commented out lines but eventually got tired of it), this copy pasted code might have some syntax error. Ignore those syntax error please.
The issue is that realloc WILL keep returning NULL.
This prevents me from readjusting it.
Can someone tell me what the hell is going on.
I know I may have made some errors here but I want to learn about it.
Yes I am just a student learning C language.

golang: pack a struct

Please consider this sample go code:
package main
//#include <stdio.h>
//#include <stdint.h>
//#pragma pack(push, 1)
//struct Packed_Struct {
// uint16_t A;
// uint16_t B;
// uint32_t C;
// uint16_t D;
//};
//#pragma pack(pop)
//
//struct UnPacked_Struct {
// uint16_t A;
// uint16_t B;
// uint32_t C;
// uint16_t D;
//};
//
//
//void print_C_struct_size(){
// struct Packed_Struct Packed_Struct;
// struct UnPacked_Struct UnPacked_Struct;
// printf("Sizeof Packed_Struct: %lu\n", sizeof(Packed_Struct) );
// printf("Sizeof UnPacked_Struct: %lu\n", sizeof(UnPacked_Struct) );
// return;
//}
//
import "C"
import(
"fmt"
"unsafe"
)
type GoStruct struct{
A uint16
B uint16
C uint32
D uint16
}
func main(){
fmt.Println("Hello world!")
meh := C.print_C_struct_size()
var GoStruct GoStruct
fmt.Printf("Sizeof GoStruct : %d\n", unsafe.Sizeof(GoStruct) )
fmt.Printf("meh type: %T\n", meh)
}
The output is:
$ go run cgo.go
Hello world!
Sizeof Packed_Struct: 10
Sizeof UnPacked_Struct: 12
Sizeof GoStruct : 12
meh type: main._Ctype_void
Notice that the struct when packed takes 10 bytes, 12 otherwise. By default, my tries in Go seems to take 12 bytes as shown here.
Is there a Go-ish way to pack this struct so it uses only 10 bytes?
So, per https://github.com/golang/go/wiki/cgo#struct-alignment-issues:
Go doesn't support packed struct (e.g., structs where maximum alignment is 1 byte), you can't use packed C struct in Go. Even if your program passes compilation, it won't do what you want. To use it, you have to read/write the struct as byte array/slice.
From "what" I understood, I've put together this: https://play.golang.org/p/OmdMVDMikSn.
Essentially, set up the struct, and binary.Write it into a byte slice, the slice shows 10 bytes.

How do I correctly find out, what size the array of structs is? [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 5 years ago.
I have the following minimal example and I don't get, why my struct sizes are wrong. I'm expecting the output to be 50, instead I get 1. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
typedef struct prod {
char *x;
} prod_t;
typedef struct obj {
prod_t *things;
} obj_t;
#define LARGE_BUF 100
#define CHAR_BUF 20
obj_t *func1(obj_t *t) {
t->things = malloc(sizeof(prod_t) * LARGE_BUF);
for (uint16_t i = 0; i < 50; i++) {
t->things[i].x = malloc(sizeof(char) * CHAR_BUF);
t->things[i].x = "hello";
}
return t;
}
int main(int argc, char **argv) {
obj_t *var = malloc(sizeof(obj_t));
var = func1(var);
printf("%lu\n", sizeof(var->things)/sizeof(var->things[0]));
return 0;
}
Since I don't have the number of entries, the function generated for me (it's 50 now, but it could change dynamically), how do I free(..) this up?
Is the only option to introduce a field in the struct, to keep track of the actual array size?
Yes you will need to add another member to the struct. For example a string wrapper type keeps track of the number of characters in it:
typdef struct {
char *base;
size_t n;
} string;
Notice n is of size_t, not int.

Resources