opaque c struct containing dynamic arrays - c

Is this the correct way to allocate memory for a c struct that contains a dynamic array? In particular, is the way I allocate memory for myStruct correct, considering that it is not yet known how big the struct actually is?
//test.h
struct Test;
struct Test * testCreate();
void testDestroy(struct Test *);
void testSet(struct Test *, int);
//test.c
#include <stdlib.h>
struct Test{
double *var;
};
struct Test * testCreate(int size){
struct Test *myTest = (struct Test *) malloc(sizeof(struct Test));
myTest->var = malloc(sizeof(double)*size);
return(myTest);
}
void testDestroy(struct Test * myTest){
free(myTest->var);
free(myTest);
}
void testSet(struct Test * myTest, int size){
int i;
for (i=0;i<size;++i){
myTest->var[i] = i;
}
}

structs have fixed size, and that's what sizeof returns.
Your struct has on element, a double pointer, and that has a (platform dependent) fixed size.
Your testCreate function does things correctly. In case you don't know the size of the dynamically allocated part, you can set the pointer to NULL to denote that the memory has to be allocated later.

Yes, you correctly malloc space for the struct and then space for the array of doubles in the struct. As a practical matter, you should always test the return from malloc() for NULL before attempting to use the memory. Also, most programs like this store the size of the array in the struct as well so you can write more general code that ensures it doesn't run off the end of the allocated space.

Related

Assignment of char array to struct with type casting

I'm working on my C program code to allocate memory without using malloc(). My friend was using a linked list to manage memory, and I do it on this example but I don't know how this type of assignment works in function memory_init().
Here's the main of the example test:
#include <string.h>
int main() {
char region[50];
memory_init(region, 50);
char* pointer = (char*) memory_alloc(10);
if (pointer) memset(pointer, 0, 10);
if (pointer) memory_free(pointer);
return 0;
}
and there's function memory_init():
void memory_init(void *ptr, unsigned size) {
struct metadata *first;
first=(struct metadata*)ptr;
first->next=NULL;
first->prev=NULL;
if (size > sizeof(struct metadata)) first->value=(size - sizeof(struct metadata));
else first->value=0;
first->boo=-1;
zac=first;
}
and there's also used struct:
struct metadata{
short boo; // if -1 free, if 1 memory used
unsigned value; //size of memory block
struct metadata *next;
struct metadata *prev;
};
So I don't know how this part of the code works:
first=(struct metadata*)ptr;
At what I see it it takes a char array sent to the function and retypes it to
a struct and assigns it, but I don't know how assignment like that works?
Does it assign a memory address or what because I don't take how I can retype
char to a struct. Basically I would like to know what happens there.
You have memory; each byte of the memory has an address.
Initially, you have void *ptr, which holds an address to some byte in memory.
When you do first=(struct metadata*)ptr; you tell the compiler, that from now I threat memory under ptr as if this memory holds struct metadata, and you use first to access that memory.
Think about it as mapping data layout defined by struct metadata to some raw memory region.
I'm not sure I understand what you are asking, but "ptr" is a void pointer and "first" is a pointer to the "metadata" struct. So "(struct metadata*)" is used as a cast.

allocating static memory for character pointer defined in struct in C

I have structure with char pointer. I want to allocate static memory to this struct member. How can I do this?
Example:
struct my_data {
int x;
bool y;
char *buf;
};
How to assign 10 bytes static memory to this char pointer? I know malloc to assign dynamic memory allocation. Is this Ok?
struct my_data data;
char buffer[10];
data.buf = &buffer[0];
PS: I am not allowed to change this struct and use malloc to assign dynamic memory.
That will be even simpler (array decays to pointer automatically):
data.buf = buffer;
note that buffer must have an ever-lasting lifetime or you have to make sure that it's not deallocated (i.e. routine where it is declared returns) while you're using it or referencing it.
Allocating from a subroutine and returning will cause underfined behaviour because memory will be deallocated on return.
For instance don't do this (as we often see in questions here):
struct my_data foo()
{
struct my_data data;
char buffer[10];
data.buf = &buffer[0];
return data;
}
int main()
{
struct my_data d = foo(); // buffer is already gone
Bugs introduced by this kind of UB are nasty because the code seems to work for a while, until the unallocated buffer gets clobbered by another function call.

what's the correct way to malloc struct pointer using sizeof?

Imagine I've the following struct
struct Memory {
int type;
int prot;
};
typedef struct Memory *Memory;
How would I initialise it using malloc()?
Memory mem = malloc(sizeof(Memory));
or
Memory mem = malloc(sizeof(struct Memory));
What is the correct way to allocate that?
Your struct declaration is a bit muddled up, and the typedef is wrong on many levels. Here's what I'd suggest:
//typedef + decl in one
typedef struct _memory {
int type;
int prot;
} Memory;
Then allocate like so:
Memory *mem = malloc(sizeof *mem);
Read the malloc call like so: "Allocate the amount of memory required to store whatever type mem is pointing to". If you change Memory *mem to Memory **mem, it'll allocate 4 or 8 bytes (depending on the platform), as it now stands it'll probably allocate 8 bytes, depending on the size of int and how the compiler pads the struct check wiki for more details and examples.
Using sizeof *<the-pointer> is generally considered to be the better way of allocating memory, but if you want, you can write:
Memory *mem = malloc(sizeof(Memory));
Memory *mem = malloc(sizeof(struct _memory));
They all do the same thing. Mind you, if you typedef a struct, that's probably because you want to abstract the inner workings of something, and want to write an API of sorts. In that case, you should discourage the use of struct _memory as much as possible, in favour of Memory or *<the-pointer> anyway
If you want to typedef a pointer, then you can write this:
typedef struct _memory {
int type;
int prot;
} *Memory_p;
In which case this:
Memory_p mem = malloc(sizeof *mem);
might seem counter intuitive, but is correct, as is:
Memory_p mem = malloc(sizeof(struct _memory));
But this:
Memory_p mem = malloc(sizeof(Memory_p));
is wrong (it won't allocate the memory required for the struct, but memory to store a pointer to it).
It's a matter of personal preference, perhaps, but I personally find typedefs obscure certain things. In many cases this is for the better (ie FILE*), but once an API starts hiding the fact you're working with pointers, I start to worry a bit. It tends to make code harder to read, debug and document...
Just think about it like this:
int *pointer, stack;
The * operator modifies a variable of a given type, a pointer typedef does both. That's just my opinion, I'm sure there are many programmers that are far more skilled than me who do use pointer typedefs.
Most of the time, though, a pointer typedef is accompanied by custom allocator functions or macro's, so you don't have to write odd-looking statements like Memory_p mem = malloc(sizeof *mem);, but instead you can write ALLOC_MEM_P(mem, 1); which could be defined as:
#define ALLOC_MEM_P(var_name, count) Memory_p var_name = malloc(count * sizeof *var_name)
or something
Both
typedef struct Memory * Memory;
and
Memory mem = malloc (sizeof (Memory));
are wrong. The correct way to do it is :
typedef struct memory
{
int type;
int prot;
} *MEMPTR;
or
struct memory
{
int type;
int prot;
};
typedef struct memory *MEMPTR;
The name of the structure should be different than the name of a pointer to it.
This construction
struct {
int type;
int prot;
} Memory;
defines an object with name Memory that has type of unnamed structure.
Thus the next construction
typedef struct Memory *Memory;
defined 1) a new type struct Memory that has nothing common with the definition above and the name Memory. and 2) another new type name Memory that is pointer to struct Memory.
If the both constructions are present in the same compilation unit then the compiler will issue an error because name Memory (the name of the pointer) in the typedef declaration tries to redeclare the object of the type of the unnamed structure with the same name Memory.
I think you mean the following
typedef struct Memory {
int type;
int prot;
} Memory;
In this case you may use the both records of using malloc like
Memory *mem = malloc( sizeof( Memory ) );
and
struct Memory *mem = malloc( sizeof( struct Memory ) );
or
Memory *mem = malloc( sizeof( struct Memory ) );
or
struct Memory *mem = malloc( sizeof( Memory ) );
because now the two identifiers Memory are in two different name spaces, The first one is used with tag struct and the second is used without tag struct.

Memory Pointers and Arrays

I have this struct:
struct table{
int miny,maxy,maxa;
int** list;
};
and its subsequent typedef:
typedef struct table *StatTable;
So, my doubt is the following:
On the initialisation of a struct table I do this and it might work fine:
StatTable newStatistic(int min,int max,int maxauts){
StatTable aux=malloc(sizeof(StatTable));
aux->miny=min;
aux->maxy=max;
aux->maxa=maxauts;
aux->list=calloc(((max-min))*(maxauts+1),sizeof(int));
return aux;
}
Since I declared that list as an int ** can I implement a function this way?
int get(StatTable st,int ano,int nAut){
return st->list[ano-getMinYear(st)][nAut];
}
StatTable aux=malloc(sizeof(StatTable));
This statement will not create an variable of struct table. StatTable is a typedef for a pointer to the struct variable so sizeof(StatTable) gives size of a pointer so this statement wont allocate space for a variable of structure.
Therefore
aux->miny=min;
aux->maxy=max;
aux->maxa=maxauts
these statements results in segmentation fault since memory is not allocated for them.
To create a variable and then to make aux a pointer to it use,
StatTable aux=malloc(sizeof(struct table));
This:
StatTable aux=malloc(sizeof(StatTable));
...is wrong. You're allocating the size of a pointer to aux. You should allocate the size of the structure instead:
StatTable aux=malloc(sizeof(struct table));
Instead allocating one contiguous block of memory like this:
aux->list=calloc(((max-min))*(maxauts+1),sizeof(int));
...you should allocate your 2D pointers like this:
aux->list = calloc(max - min, sizeof(*aux->list));
for (int i=0; i<max-min; i++)
aux->list[i] = calloc(maxauts + 1, sizeof(**aux->list));

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