Table of struct allocate C - c

This is my structure:
typedef struct wyraz{
char *slowo;
char *tlumaczenie;
struct wyraz *nastepny;
}WYRAZ;
typedef struct lista_tlumaczen{
char znak;
WYRAZ *lista_znakowa;
}LISTA_TLUMACZEN;
I want to have something like that
LISTA_TLUMACZEN tab[5];
but dynamic allocation I don't know how to do this, can someone help me?

When you have embedded pointers to structures you need to think of memory allocation in layers. Starting at the highest level first in this case works best. So start with:
LISTA_TLUMACZEN tab[5];
Here you're saying you want a table of pLISTA_TLUMACZEN structures. If you want this to be dynamic, then you need a pointer to a LISTA_TLUMACZEN:
LISTA_TLUMACZEN *tab;
Then to allocate it, you need to determine how big it is. In this case, we'll say NUMBER_OF_ELEMENTS:
tab = (LISTA_TLUMACZEN *)malloc(sizeof(LISTA_TLUMACZEN) * 5);
If you want to be especially safe that the malloc parameter isn't out of range you can use:
tab = (LISTA_TLUMACZEN *)(NUMBER_OF_ELEMENTS <= (SIZE_MAX / sizeof(LISTA_TLUMACZEN)) ? malloc(sizeof(LISTA_TLUMACZEN) * 5) : NULL);
Now we have the dynamically allocated equivalent of your tab[5] data declaration. Note that it's a table of LISTA_TLUMACZEN structures. So the amount of memory to allocate is the product of 5 and the size of the structure.
Your LISTA_TLUMACZEN structure also has a pointer to another structure with more pointers. You can allocate those following the same kind of logic or actually only as needed when the program needs them and freeing them when they're no longer needed (which is the reason for having dynamic allocation). If all you do is pre-allocate everything with malloc then there's no point and you may as well statically declare everything.

Related

Dinamically vs Static memory allocation for a struct array

If you want to allocate an array of struct you can do it statically by declaring something like
struct myStruct myStructArray[100];
or dinamically with something like
struct myStruct *myStructArray = calloc(100, sizeof(struct myStruct) );
but in this case you are responsible for freeing the memory.
In many applications and samples I found a mixed approach:
struct wrapperStruct
{
int myInt;
struct myStruct myStructArray[1];
};
Then the allocation is performed like this
int n = 100;
size_t memory_size = sizeof(struct wrapperStruct) + (n - 1) * sizeof(struct myStruct);
struct wrapperStruct *wrapperStruct_p = calloc(1, memory_size);
So (if I understood correctly) since the array is the last member of the struct and the field of a struct respect the same position in memory then you are "extending" the single entry array myStructArray with 99 entries.
This allow you to safety write something like wrapperStruct_p.myStructArray[44] without causing a buffer overflow and without having to create a dynamic allocated array of struct and then take care of the memory disposal at the end. So the alternative approach would be:
struct wrapperStruct
{
int myInt;
struct myStruct *myStructArray;
};
struct wrapperStruct *wrapperStruct_p = calloc(1, sizeof(struct wrapperStruct) );
wrapperStruct_p.myStructArray = calloc(100, sizeof(struct myStruct) )
The question is what happens when you try to free the wrapperStruct_p variable ?
Are you causing a memory leak ?
Is the C memory management able to understand that the array of struct is made of 100 entries and not 1 ?
What are the benefits of the first approach apart from not having to free the pointer inside the struct ?
The question is what happens when you try to free the wrapperStruct_p
variable ?
Are you causing a memory leak ?
Most likely, but not necessary. The memory for the inner dynamic array is not freed, but you could still free it later if you saved the pointer address to some other variable.
Is the C memory management able to understand that the array of struct is made of 100 entries and not 1 ?
"C memory management" takes care of stack and heap allocations (the latter using systemcalls so maybe it's not really a "C memory management"), it doesn't do much else other than provide syntactic sugar on top of assembler (unlike garbage collected languages like Java or other).
C itself doesn't care about how many entries are somewhere and what part of memory you access (SEGFAULTS are the OS response to memory access violations)
What are the benefits of the first approach apart from not having to
free the pointer inside the struct ?
If by "first approach" you mean stack allocated array, then it's mainly the fact that you do not need to allocate anything and the stack does it for you (drawback being that it stays allocated in the declared scope and you can't free up or increase the array space) then the constant allocation speed and assurance you'll get your 100 array items no matter the OS response (many realtime applications require maximum response times, therefore a heap allocation can be a really big slowdown causing problems).
If by "first approach" you mean using the wrapper struct, then I do not see any benefits other than the one you already stated.
I'd even suggest you not advocate/use this approach, since it is a really confusing technique that doesn't serve noticeable benefits (plus it allocates 1 space even though it may not be even used, but that's a detail)
The main goal is to write code that is easily understandable by other people. Machines and compilers can nowadays do wonders with code, so unless you are a compiler designer, standard library developer or machine level programmer for embedded systems, you should write simple to understand code.

At what size should I malloc structs?

Most examples using structs in C use malloc to assign the required size block of memory to a pointer to that struct. However, variables with basic types (int, char etc.) are allocated to the stack and it is assumed that enough memory will be available.
I understand the idea behind this is that memory may not be available for larger structs so we use malloc to ensure we do indeed have enough memory but in the case of our struct being small is this really necessary? For example if a struct only consists of three ints, surely I am always fine to assume there is enough memory?
So really my question boils down to what are the best practises in C regarding when it is necessary to malloc variables and what is the justification?
The only time you don't have to allocate memory is when you statically allocate memory, which is what happens when you have a statement like:
int number = 5;
You can always write it as:
int *pNumber = malloc(sizeof(int));
but you have to make sure to free it or you will be leaking memory.
You can do the same thing with a struct (instead of dynamically allocating memory for it, statically allocate):
struct some_struct_t myStruct;
and access members by:
myStruct.member1 = 0;
etc...
The big difference between dynamic allocation and static is whether that data is available outside of your current scope. With static allocation, it's not. With dynamic it is, but you have to make sure to free it.
Where you run into trouble is when you have to return a structure (or a pointer to it) from a function. You either have to dynamically allocate inside the function which is returning it or you have to pass in a pointer to an externally (dynamically or statically) allocated structure which the function can then work with.
Good code gets re-used. Good code have few size limitations. Write good code.
Use malloc() whenever there is anything more than trivial buffer sizes.
Buffer size to write an int: The needed buffer size is at most sizeof(int)*CHAR_BIT/3 + 3. Use a fixed buffer.
Buffer size to write a double as in sprintf(buf, "%f",...: The needed buffer size could be thousands of bytes: use malloc(). Or use sprintf(buf, "%e",... and use a fixed buffer.
Forming a file path name could involve thousands of char. Use malloc().

How is dynamically allocated memory kept track in C [duplicate]

This question already has answers here:
How does free know how much to free?
(11 answers)
Closed 9 years ago.
we allocate memory dynamically in C using malloc() and we receive a pointer to a location in the heap.
now we use free() to deallocate the memory, passing the same pointer value as its argumnet.
the Question now is how does free() know how much to deallocate.. considering the fact that we can always resize the memory block allocated by malloc().
is there anything related to Hash Tables here?
A typical implementation will store information just before the address returned by malloc. That information will include the information that realloc or free needs to know to do their work, but the details of what exactly is stored there depends on the implementation.
The original technique was to allocate a slightly larger block and store the size at the beginning, a part the application didn't see. The extra space holds a size and possibly links to thread the free blocks together for reuse.
There are certain issues with those tricks, however, such as poor cache and memory management behavior. Using memory right in the block tends to page things in unnecessarily and also create dirty pages which complicate sharing and copy-on-write.
So a more advanced technique is to keep a separate directory. Exotic approaches have also been developed where areas of memory use the same power-of-two sizes.
In general, the answer is: a separate data structure is allocated to keep state.
A simplist implementation is the one in the famous K&R C Bible,page 186 - 188.
The memory block we get actually is more (a struct head's or a union head's size) than we apply for.The struct may be like this:
typedef long Align;
union header
{
struct
{
union header* ptr; // next block
unsigned size; // size of this block , times of head size
}s;
Align x;
};
A figure to demonstrate it:
When we call the free function, the behaviour may be like this:
void free(void* ptr)
{
Header *bp, *p;
bp = (Header *)ptr - 1;
/* ..... */
/*return the memory to the linked list */
}
In visual studio, we have two models: release version and debug version,we could even use
the head to store debug message to make debug easier.The header in debug version is called _CrtMemBlockHeader, the definition is as below :
typedef struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader * pBlockHeaderNext;
struct _CrtMemBlockHeader * pBlockHeaderPrev;
char * szFileName;
int nLine;
size_t nDataSize;
int nBlockUse;
long lRequest;
unsigned char gap[nNoMansLandSize];
} _CrtMemBlockHeader;
Then the memory lalout is:
A memory manager uses tables to store additional data based on a pointer, sometimes right before the pointer, sometimes elsewhere. With C being very simple, the data is most likely pointer-2 or pointer-4, as int or long type. The correct details depend on the compiler.
When we use malloc ,a block will get reserve whose size will be littile more than what we have requested and in return to this malloc we get a pointer to start of this block.
AS i told you size of this block will be littile more than what exactly you needed.This extra space will be used to keep actual requested size of block,pointer to next free block and some data which checks "if you trying to access more than allocated block".
So whenever we call free using the pointer we want to deallocate, this free will search for the extra information given in the block space, Where it gets final size to deallocate.

malloc twice for structure

I have a structure as below
typedef struct Mystruct{
char *name;
int telno;
struct Mystruct *nextp;
}data;
Now I malloc the structure
data *addnode;
addnode = malloc (sizeof(data));
Now I would add data to the char *name.
addnode->name = malloc (sizeof(MAX));
Question:Why is it required to malloc again?
I was under the assumption that malloc-ing the addnode will even allocate the memory for addnode->name but it is not so.
malloc is not deep and doesn't do recursion. So it won't allocate memory for any of the pointers inside the structure you pass.
If you think about this a bit more, you can see that must be so. You don't pass in any information about the structure you are allocating. You just pass a size for the memory block. Now, malloc doesn't even know what type of data you are allocating. It doesn't know that the block itself contains a pointer.
As for why this design choice was made, how can the library tell who owns the memory that your pointer refers to? Perhaps it's owned by that structure. Or perhaps you want to use that pointer to refer to some memory allocated elsewhere. Only you can know that which is why the responsibility falls to you. In fact your structure is a fine example of this. Probably the name member is owned by the structure, and the nextp member is not.
Allocating memory for Mystruct provides enough memory for a pointer to name. At this point we have no idea how many characters will be in a name so can't possibly allocate the memory for it.
If you want to fully allocate the structure in a single allocation, you could decide on a max size for name and change the structure definition to
#define MAX_NAME (10) /* change this as required */
typedef struct Mystruct{
char name[MAX_NAME];
int telno;
struct Mystruct *nextp;
}data;
Or, if you know the name when you allocate the struct, you could hide the need for two allocations from the caller by providing a constructor function
struct Mystruct* Mystruct_create(const char* name)
{
Mystruct* ms = malloc(sizeof(*ms));
ms->name = strdup(name);
return ms;
}
No. first malloc() allocates memory to whole structure including memory for holding pointer to name. i.e 4 bytes in 32 bit OS.
You need to allocate memory separately for holding data in it. by default that pointer will be pointing to some garbage location, if not initialized.
same case for free() too. i.e you have to free the inner blocks first, then free the memory for whole structure. There is no recursion kind of things in malloc() and free().

When and why to use malloc

Well, I can't understand when and why it is needed to allocate memory using malloc.
Here is my code:
#include <stdlib.h>
int main(int argc, const char *argv[]) {
typedef struct {
char *name;
char *sex;
int age;
} student;
// Now I can do two things
student p;
// Or
student *ptr = (student *)malloc(sizeof(student));
return 0;
}
Why is it needed to allocate memory when I can just use student p;?
malloc is used for dynamic memory allocation. As said, it is dynamic allocation which means you allocate the memory at run time. For example, when you don't know the amount of memory during compile time.
One example should clear this. Say you know there will be maximum 20 students. So you can create an array with static 20 elements. Your array will be able to hold maximum 20 students. But what if you don't know the number of students? Say the first input is the number of students. It could be 10, 20, 50 or whatever else. Now you will take input n = the number of students at run time and allocate that much memory dynamically using malloc.
This is just one example. There are many situations like this where dynamic allocation is needed.
Have a look at the man page malloc(3).
You use malloc when you need to allocate objects that must exist beyond the lifetime of execution of the current block (where a copy-on-return would be expensive as well), or if you need to allocate memory greater than the size of that stack (i.e., a 3 MB local stack array is a bad idea).
Before C99 introduced VLAs, you also needed it to perform allocation of a dynamically-sized array. However, it is needed for creation of dynamic data structures like trees, lists, and queues, which are used by many systems. There are probably many more reasons; these are just a few.
Expanding the structure of the example a little, consider this:
#include <stdio.h>
int main(int argc, const char *argv[]) {
typedef struct {
char *name;
char *sex;
char *insurance;
int age;
int yearInSchool;
float tuitionDue;
} student;
// Now I can do two things
student p;
// Or
student *p = malloc(sizeof *p);
}
C is a language that implicitly passes by value, rather than by reference. In this example, if we passed 'p' to a function to do some work on it, we would be creating a copy of the entire structure. This uses additional memory (the total of how much space that particular structure would require), is slower, and potentially does not scale well (more on this in a minute). However, by passing *p, we don't pass the entire structure. We only are passing an address in memory that refers to this structure. The amount of data passed is smaller (size of a pointer), and therefore the operation is faster.
Now, knowing this, imagine a program (like a student information system) which will have to create and manage a set of records in the thousands, or even tens of thousands. If you pass the whole structure by value, it will take longer to operate on a set of data, than it would just passing a pointer to each record.
Let's try and tackle this question considering different aspects.
Size
malloc allows you to allocate much larger memory spaces than the one allocated simply using student p; or int x[n];. The reason being malloc allocates the space on heap while the other allocates it on the stack.
The C programming language manages memory statically, automatically, or dynamically. Static-duration variables are allocated in main memory, usually along with the executable code of the program, and persist for the lifetime of the program; automatic-duration variables are allocated on the stack and come and go as functions are called and return. For static-duration and automatic-duration variables, the size of the allocation must be compile-time constant (except for the case of variable-length automatic arrays[5]). If the required size is not known until run-time (for example, if data of arbitrary size is being read from the user or from a disk file), then using fixed-size data objects is inadequate. (from Wikipedia)
Scope
Normally, the declared variables would get deleted/freed-up after the block in which it is declared (they are declared on the stack). On the other hand, variables with memory allocated using malloc remain till the time they are manually freed up.
This also means that it is not possible for you to create a variable/array/structure in a function and return its address (as the memory that it is pointing to, might get freed up). The compiler also tries to warn you about this by giving the warning:
Warning - address of stack memory associated with local variable 'matches' returned
For more details, read this.
Changing the Size (realloc)
As you may have guessed, it is not possible by the normal way.
Error detection
In case memory cannot be allocated: the normal way might cause your program to terminate while malloc will return a NULL which can easily be caught and handled within your program.
Making a change to string content in future
If you create store a string like char *some_memory = "Hello World"; you cannot do some_memory[0] = 'h'; as it is stored as string constant and the memory it is stored in, is read-only. If you use malloc instead, you can change the contents later on.
For more information, check this answer.
For more details related to variable-sized arrays, have a look at this.
malloc = Memory ALLOCation.
If you been through other programming languages, you might have used the new keyword.
Malloc does exactly the same thing in C. It takes a parameter, what size of memory needs to be allocated and it returns a pointer variable that points to the first memory block of the entire memory block, that you have created in the memory. Example -
int *p = malloc(sizeof(*p)*10);
Now, *p will point to the first block of the consecutive 10 integer blocks reserved in memory.
You can traverse through each block using the ++ and -- operator.
In this example, it seems quite useless indeed.
But now imagine that you are using sockets or file I/O and must read packets from variable length which you can only determine while running. Or when using sockets and each client connection need some storage on the server. You could make a static array, but this gives you a client limit which will be determined while compiling.

Resources