size of a struct in c equals to 1 - c

For some reason if I try to get the actual size of mystruct I keep getting size 1.
I know that mystruct is holding the data cause I can dump it out and everything is in mystruct.
What could be the reason of getting size 1?
Thanks
// fragments of my code
struct mystruct {
char *raw;
int count;
};
struct counter {
int total; // = 30
}
static struct mystruct **proc()
{
int i = 0;
gchar *key,*val;
struct mystruct **a_struct;
struct counter c;
a_struct = (struct mystruct **)malloc(sizeof(struct mystruct *)*c.total);
while (table (&iter, (gpointer) &key, (gpointer) &val)) {
a_struct[i] = (struct mystruct *)malloc(sizeof(struct mystruct));
a_struct[i]->raw = (char*)key;
a_struct[i++]->count = (int)val;
}
size_t l = sizeof(a_struct) / sizeof(struct mystruct*);
printf("%d",l); // outputs 1
}

You're doing a couple things wrong. First, you're taking sizeof(a_struct) which is going to be the size of a pointer (since that's what a_struct is) and then dividing by the size of another pointer. Guaranteed 1.
Besides that, why are you doing a division at all? What I think you want is:
size_t l = sizeof(struct mystruct);
or
size_t l = sizeof(**a_struct);
Edit:
I think I see the reason for your division now; you're trying to find the size of that array. That's not going to work - sizeof can only work at compile time in C (with some special exceptions in C99 which don't apply to your code), so it can't figure out the size of a dynamic array like that.

you're dividing the size of a pointer by the size of a pointer.

a_struct is a double pointer to struct mystruct.
struct mystruct * is a pointer to struct mystruct.
Both there sizes will be same.
Do this size_t l = sizeof(struct mystruct);

You are taking the size of two pointers and dividing one by the other,
size_t l = sizeof(a_struct) / sizeof(struct mystruct*);
a_struct is declared as struct mystruct **a_struct so this is the same as saying
size_t l = sizeof(struct mystruct **) / sizeof(struct mystruct*);
since all pointers have the same size, ** is the same size as *, so this will always evaluate to 1.
I'm not quite sure what you are trying to print out here, the size of a_struct ? or the total allocation size? The size of a_struct is just c.total, the total allocation is the sum of all of the values that you passed to malloc.

Related

Allocate a structure by calloc(): To which value the members are initialized?

For example I have a struct
struct s{
char c;
int x;
};
And I use calloc() to allocate memory.
s *sp = (s*) calloc(1, sizeof(s));
Now, what will be the values of sp->c and sp->x?
"What will be the values of sp->c and sp->x?"
Since calloc() sets all bits of the allocated memory to 0, c and x will have the value of 0 if the 0 value representation of int and char is of all bits to 0 (which is common).
Note that in the case of pointers, the pointer might not be standard-compliant NULL pointer when just setting all bits to 0 as the C standard does not require the representation of NULL pointers to be all-zero-bits.
Side notes:
1.
struct s{
char c;
int x;
};
s *sp = (s*) calloc(1, sizeof(s));
can´t work as s isn´t a typedefd type; it is a structure tag. Therefore, You need to precede s by the struct keyword:
struct s *sp = (struct s*) calloc(1, sizeof(struct s));
2.
You do not need to cast the returned pointer from calloc() and other memory management functions and rather avoid it since it can add clutter to your code. -> Do I cast the result of malloc
So, just do:
struct s *sp = calloc(1, sizeof(struct s));

Generic array searcher and padding

I've been trying to implement a generic array searcher and came across this answer, which made me think that my implementation is only valid for dynamically allocated arrays.
The implementation looks like this:
void *array_search( void *arr,
size_t elem_size,
size_t len,
arr_search_checker v,
void *match)
{
char *p = arr;
for(unsigned i = 0; i < len; ++i)
{
if(v((void *) p, match))
return p;
p += elem_size;
}
return NULL;
}
The type arr_search_checker:
typedef bool (*arr_search_checker)(void *, void *);
Having a simple structure:
struct test_struct { int i; char c; };
And a check function:
bool test_checker(void *l, void *r)
{
struct test_struct *ls = l, *rs = r;
return ls->i == rs->i && ls->c == rs->c;
}
And array of length len which is an array of struct test_struct one can invoke the searcher:
struct test_struct match = { .i = 5, .c = 'A' };
struct test_struct *res = array_search(array,
sizeof(struct test_struct), len, test_checker, &match);
Is that true that this implementation of array_search is only valid for dynamically allocated arrays because of incrementation of the char pointer p by size of the single element in the array what can be dangerous for padded arrays? Or is it totally invalid?
Please state your question in the question topic.
The function array_search as valid for any arrays (don't know why dynamically allocated arrays are particular in any way). Char pointer p is incremented by elem_size. elem_size is assigned the value of sizeof(struct test_struct) in your example and that's perfectly ok. Padding has nothing to do with it. Imagine struct test_struct has some padding bytes added to it (anywhere, at the end of the structure or between any of it members). Then sizeof(struct test_struct) will be the size of the test_struct structure including the padding bytes, and p will still be increment correctly.
You may convert any pointer to void* and any pointer to char* without braking the strict aliasing rule. You cannot do arithmetic on void* pointers, that's why it gets converted to char* pointer. elem_size represents the size of a single array element in bytes, char represents one byte in memory, by doing p += elem_size; you add elem_size bytes to p (I like the form p = &p[elem_size];). The smallest addressable size in C is one byte (remember that byte may not be 8 bits) and the size of every structure or type in C must be an integral value (ie. sizeof(struct test_struct) cannot return 1,5).
For more, look at bsearch and qsort functions from standard C library. They have a very similar declaration to array_search and work with any array types, just like array_search here.

C struct with array size determined at compile time

How does one build a struct with an array that can be set differently for each struct, ideally by a parameter? The application being a single data type that supports arrays of different, but fixed lengths
My attempt looks somehting like this, which obviously didnt compile:
struct Data_struct(n)
{
int xData[n];
int test;
};
The only method available is to use a flexible array member.
struct Data_struct {
int test;
int xData[];
};
You would then allocate space for this using malloc():
int n = 4;
struct Data_struct *s = malloc(sizeof(struct Data_struct) + n * sizeof(int));
Note that we had to explicitly allocate additional space for the flexible array.
You can dynamically allocate the array
struct Data_struct
{
int * xData;
int test;
};
....
s.xData = calloc(size, sizeof(int))
and remember to free xData when finished
Normally you would define a variable length array at the end of the struct, and then fix up the size at run-time, e.g.
typedef struct
{
int test;
int xData[1];
} Data_struct;
To allocate a struct such as this with a size of n for xData you'd do soemthing like this:
Data_struct * s = malloc(sizeof(Data_struct) + (n - 1) * sizeof(int));
One might call this ugly but here goes. Use a #define
#define foo(n) struct Data_struct##n { int test; int xData[n]; }
foo(20);
struct Data_struct20 abc;
The foo(20) defines a structure with n = 20 characters.
You could use another #define for the allocation of space if you wish.

write your own malloc

I am writing my own malloc() and i have already figured the following
struct myblock
{
struct myblock *next;
struct myblock *prev;
int isFree;
unsigned availablesize;
char *buffer;
}
and space #define MEM_BUFFER (1024) which will be "my ram".
and if i am not wrong then i would have
char *array[MEM_BUFFER];
to have array of 1024 bytes (kindly correct me if i am wrong).
As we know that MEM_BUFFER will also contain the matadata of occupied space. I am bit confused that how should i start.
This is my main question.
should i assign the struct to the array on each allocation request (if yes then from struct char array ?) .
should i handle double linked list on heap and skip sizeof(myblock) bytes from the array.
I am thinking on this solution for last 2 days and I am still confused.
No,
char *array[MEM_BUFFER];
is not an array of 1024 bytes (unless MEM_BUFFER is set to 1024 / sizeof (char *)) typically. It's an array of MEM_BUFFER character pointers.
You need just:
char array[MEM_BUFFER];
although a better name might be heap_space.
To make it consist of blocks, you'd need an additional pointer that is the first block:
struct myblock *heap = (struct myblock *) heap_space;
Then you can initialize that:
heap->next = NULL;
heap->prev = NULL;
heap->isFree = 1;
heap->availablesize = sizeof heap_space - sizeof *heap;
Not sure what struct myblock.buffer should do, I put the blocks inside the heap so the user memory for a block is at (void *) (block + 1);

Allocating memory for a Structure in C

I'm tasked to create a program which dynamically allocates memory for a structure.
normally we would use
x=malloc(sizeof(int)*y);
However, what do I use for a structure variable?
I don't think its possible to do
struct st x = malloc(sizeof(struct));
Could someone help me out?
Thanks!
My favorite:
#include <stdlib.h>
struct st *x = malloc(sizeof *x);
Note that:
x must be a pointer
no cast is required
include appropriate header
You're not quite doing that right. struct st x is a structure, not a pointer. It's fine if you want to allocate one on the stack. For allocating on the heap, struct st * x = malloc(sizeof(struct st));.
struct st* x = malloc( sizeof( struct st ));
It's exactly possible to do that - and is the correct way
Assuming you meant to type
struct st *x = malloc(sizeof(struct st));
ps. You have to do sizeof(struct) even when you know the size of all the contents because the compiler may pad out the struct so that memebers are aligned.
struct tm {
int x;
char y;
}
might have a different size to
struct tm {
char y;
int x;
}
This should do:
struct st *x = malloc(sizeof *x);
struct st *x = (struct st *)malloc(sizeof(struct st));
I believe, when you call sizeof on a struct type, C recursively calls sizeof on the fields of the struct. So, struct st *x = malloc(sizeof(struct st)); only really works if struct st has a fixed size. This is only significant if you have something like a variable sized string in your struct and you DON'T want to give it the max length each time.
In general,
struct st *x = malloc(sizeof(struct st));
works. Occasionally, you will run into either variable sized structs or 'abstract' structs (think: abstract class from Java) and the compiler will tell you that it cannot determine the size of struct st. In these cases, Either you will have to calculate the size by hand and call malloc with a number, or you will find a function which returns a fully implemented and malloc'd version of the struct that you want.

Resources