Pointer as a structure variable in c - c

When I use code like this :
typedef struct {
int x;
int *pInt;
} tData;
tData *ptData = malloc(sizeof(tData));
If i understand it right, i allocated memory with size of tData and returned adress to this allocated memory to pointer *ptData.
But what if i used this code :
typedef struct {
int x;
int *pInt;
} *tData;
If I want to allocate memory to this struct, do I need a struct name? Because for me, if I allocate like malloc(sizeof(*tData));, it seems to me like I am allocating memory only for the pointer, not for the structure itself. When I want to refer to data in this structure, do I need to use pointer to pointer to a struct?
It confuses me a bit and I couldn't find the answer I am looking for.
Thank you for any explanation!

This is one of the reason one should avoid creating type-aliases of pointers.
As for how to use it, instead of passing the type to the sizeof operator, use the variable. Like e.g.
typedef struct {
int x;
int *pInt;
} *tData;
tData ptData = malloc(sizeof *ptData); // Allocate memory for one structure

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.

How to allocate memory dynamically for a struct [duplicate]

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

how do pointers work when i try to make one take the value of another

So, let s say i have the following structure
typedef struct
{
void * value;
}Info;
typedef struct
{
char* title;
int nrOfPages;
}Book;
I allocate memory in main for Book snowWhite and then i want to call a function that will allocate an Info struct, and will make the value pointer, point to snowWhite.For this i was thinking to make:
((Info*)p)->value = snowWhite
(i declare snowWhite in main as a Book type pointer: Book* snowWhite)
Is it correct? Will this (((Info*)p)->value = snowWhite) make the value pointer to the memory that i have allocated to snowWhite?

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.

Categories

Resources