I am new at C language and I need to create a queue and I don´t if I need to use a malloc (memory allocation) and how to use it. I had run add, remove, size and isempty without malloc and it worked.
void e1_init(e1queue_t* q){
q->head = 0;
q->tail = sizeof(q->queue)/sizeof(int)-1;
q->size=0;
}
Thanks.
In C, there are two kinds of memory:
The Stack
The Heap
Stack memory is rather limited and is used for automatic variables in functions, processing overhead, things like that.
When you need a larger chunk of memory, you need to get it from the heap.
Not an exact duplicate of this answer, but this seems to be a good description:
What and where are the stack and heap?
C dynamic memory allocation refers to performing dynamic memory allocation in the C programming language via a group of functions in the C standard library, namely malloc, realloc, calloc and free
Syntax:
#include <stdlib.h>
Description:
The function malloc() returns a pointer to a chunk of memory of size size, or NULL if there is an error. The memory pointed to will be on the heap, not the stack, so make sure to free it when you are done with it.
Example:
typedef struct data_type {
int age;
char name[20];
} data;
data *bob;
bob = (data*) malloc( sizeof(data) );
if( bob != NULL ) {
bob->age = 22;
strcpy( bob->name, "Robert" );
printf( "%s is %d years old\n", bob->name, bob->age );
}
free( bob );
Good Read C dynamic memory allocation
There are many reasons to use malloc() function.
malloc() is used to dynamically allocate memory for variables.
why?
There can be many reasons to allocate memory dynamically. For instance if the size of a certain object/variable isn't known at COMPILE time, and there might be a reason to increase it later on, then its required to increase the memory requirement. and this is where malloc comes in.
malloc() is used to initialize POINTERS
why?
POINTERS that aren't initialized point to a random location. This location may be in-accessible and might crash the program. When malloc is used, it increases the heap storage and points the randomly initialized pointer to a "sane" location, which can be read/written to.
also, pointers initialized with malloc can be resized using realloc() method. This makes memory management flexible(and error prone as well)
Related
I have been reading that malloc is used for dynamic memory allocation. But if the following code works...
int main(void) {
int i, n;
printf("Enter the number of integers: ");
scanf("%d", &n);
// Dynamic allocation of memory?
int int_arr[n];
// Testing
for (int i = 0; i < n; i++) {
int_arr[i] = i * 10;
}
for (int i = 0; i < n; i++) {
printf("%d ", int_arr[i]);
}
printf("\n");
}
... what is the point of malloc? Isn't the code above just a simpler-to-read way to allocate memory dynamically?
I read on another Stack Overflow answer that if some sort of flag is set to "pedantic", then the code above would produce a compile error. But that doesn't really explain why malloc might be a better solution for dynamic memory allocation.
Look up the concepts for stack and heap; there's a lot of subtleties around the different types of memory. Local variables inside a function live in the stack and only exist within the function.
In your example, int_array only exists while execution of the function it is defined in has not ended, you couldn't pass it around between functions. You couldn't return int_array and expect it to work.
malloc() is used when you want to create a chunk of memory which exists on the heap. malloc returns a pointer to this memory. This pointer can be passed around as a variable (eg returned) from functions and can be used anywhere in your program to access your allocated chunk of memory until you free() it.
Example:
'''C
int main(int argc, char **argv){
int length = 10;
int *built_array = make_array(length); //malloc memory and pass heap pointer
int *array = make_array_wrong(length); //will not work. Array in function was in stack and no longer exists when function has returned.
built_array[3] = 5; //ok
array[3] = 5; //bad
free(built_array)
return 0;
}
int *make_array(int length){
int *my_pointer = malloc( length * sizeof int);
//do some error checking for real implementation
return my_pointer;
}
int *make_array_wrong(int length){
int array[length];
return array;
}
'''
Note:
There are plenty of ways to avoid having to use malloc at all, by pre-allocating sufficient memory in the callers, etc. This is recommended for embedded and safety critical programs where you want to be sure you'll never run out of memory.
Just because something looks prettier does not make it a better choice.
VLAs have a long list of problems, not the least of which they are not a sufficient replacement for heap-allocated memory.
The primary -- and most significant -- reason is that VLAs are not persistent dynamic data. That is, once your function terminates, the data is reclaimed (it exists on the stack, of all places!), meaning any other code still hanging on to it are SOL.
Your example code doesn't run into this problem because you aren't using it outside of the local context. Go ahead and try to use a VLA to build a binary tree, then add a node, then create a new tree and try to print them both.
The next issue is that the stack is not an appropriate place to allocate large amounts of dynamic data -- it is for function frames, which have a limited space to begin with. The global memory pool, OTOH, is specifically designed and optimized for this kind of usage.
It is good to ask questions and try to understand things. Just be careful that you don't believe yourself smarter than the many, many people who took what now is nearly 80 years of experience to design and implement systems that quite literally run the known universe. Such an obvious flaw would have been immediately recognized long, long ago and removed before either of us were born.
VLAs have their place, but it is, alas, small.
Declaring local variables takes the memory from the stack. This has two ramifications.
That memory is destroyed once the function returns.
Stack memory is limited, and is used for all local variables, as well as function return addresses. If you allocate large amounts of memory, you'll run into problems. Only use it for small amounts of memory.
When you have the following in your function code:
int int_arr[n];
It means you allocated space on the function stack, once the function will return this stack will cease to exist.
Image a use case where you need to return a data structure to a caller, for example:
Car* create_car(string model, string make)
{
Car* new_car = malloc(sizeof(*car));
...
return new_car;
}
Now, once the function will finish you will still have your car object, because it was allocated on the heap.
The memory allocated by int int_arr[n] is reserved only until execution of the routine ends (when it returns or is otherwise terminated, as by setjmp). That means you cannot allocate things in one order and free them in another. You cannot allocate a temporary work buffer, use it while computing some data, then allocate another buffer for the results, and free the temporary work buffer. To free the work buffer, you have to return from the function, and then the result buffer will be freed to.
With automatic allocations, you cannot read from a file, allocate records for each of the things read from the file, and then delete some of the records out of order. You simply have no dynamic control over the memory allocated; automatic allocations are forced into a strictly last-in first-out (LIFO) order.
You cannot write subroutines that allocate memory, initialize it and/or do other computations, and return the allocated memory to their callers.
(Some people may also point out that the stack memory commonly used for automatic objects is commonly limited to 1-8 mebibytes while the memory used for dynamic allocation is generally much larger. However, this is an artifact of settings selected for common use and can be changed; it is not inherent to the nature of automatic versus dynamic allocation.)
If the allocated memory is small and used only inside the function, malloc is indeed unnecessary.
If the memory amount is extremely large (usually MB or more), the above example may cause stack overflow.
If the memory is still used after the function returned, you need malloc or global variable (static allocation).
Note that the dynamic allocation through local variables as above may not be supported in some compiler.
I have the following piece of code. I want to properly free all my memory. As you can see, I have a b_struct within an a_struct. I wonder whether I need to manually free the b_struct within the a_struct, and if so, what is the proper way to do it?
#include <stdlib.h>
#include <stdio.h>
struct b_struct {
int c;
};
struct a_struct {
struct b_struct b;
};
int main(int argc, char **argv)
{
struct a_struct *a;
a = calloc(1, sizeof(*a));
a->b.c = 5;
printf("Value: %d", a->b.c);
free(a);
}
I wonder whether I need to manually free the b_struct within the a_struct
No.
From the malloc(3) man page:
The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc(), or realloc().
When you allocated sizeof(struct a_struct) bytes, that includes all members of that structure, including the struct b_struct member. This struct member is no different than an int or char[] member; it's all just one contiguous block of memory to the allocator.
No. Not only do you not need to, you are not allowed to. The memory used in b is a part of the memory used in a; you need to free the latter as a single unit, and that includes all of the memory for b.
In general, your program should call free exactly once for each call to malloc or calloc. This doesn’t mean the number of lines of code calling free needs to be the same as the number of lines calling allocation functions; it means that each time you run the program, each call to free should be paired with exactly one call to an allocation function, and vice versa, with limited exceptions:
If the allocation fails (and returns NULL), you don’t need to call free on NULL.
You can call free on NULL as many times as you want, although you usually don’t want.
You might call library functions which then allocate or free memory internally. This isn’t really an exception; each of those functions must still be matched with a corresponding free or allocation (respectively), but if you just look at malloc, calloc, and free you might miss something.
When your earliest opportunity to free a chunk of memory is right before the program exits, you don’t need to bother, because the OS reclaims all the memory atthat point anyway. This point in particular has its own caveats, but they are at best tangential to this issue.
If you fail to free memory which was allocated, you have a memory leak. Your program will use more and more memory until the OS can’t give it any more, at which point it will probably crash.
If you free memory which was not allocated by one of the standard allocation functions, or free the same memory twice, it gets even worse: this is immediately undefined behavior (UB) and might do anything*. This is the type of bug you would introduce by trying to free b; the memory in question was not the actual pointer returned by calloc, and even if it were it would have already been freed as part of a.
* People often say UB might do anything a lot, but in practice you can often predict what will happen on a real system; it won’t make your computer explode unless you actually have a USB bomb plugged into the computer in question. However, I would classify invalid frees as one of the less-tame types of UB: the errors it introduces can in practice appear later than the actual bug, cause seemingly unrelated issues, and be unstable between multiple runs of the program (meaning things might look fine when you test but fail when you try to use the program, and be hard to debug). With many other forms of UB this is allowed but not as likely in practice to happen.
In this case, no.
You would only need to manually free the inner struct if it was allocated separately from the outer struct. Example:
struct a_struct
{
struct b_struct *b;
};
int main( void )
{
struct a_struct *a = malloc( sizeof *a );
if ( a ) // *Always* check the result of malloc or calloc
{
a->b = malloc( sizeof *a->b );
if ( a->b )
{
// do stuff with a->b->c
free( a->b ); // free in reverse order that you allocated
}
free( a );
}
return 0;
}
You should only free pointer values returned from malloc, calloc, or realloc.
I wish to free blocks of memory which I don't have pointers to. In my program, I call malloc sequentially, hoping that the memory created by malloc(1), malloc(4), malloc(5) is continuous. Then I free these memory when I only have the pointer to malloc(5). But I can't think of how this can be done; I cannot simply create a pointer that reference to the address of ptr[-5] and then free 5 bytes of memory? How can this be done?
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
malloc(1);
malloc(4);
char* ptr = malloc(5);
free(ptr);
}
You cannot do what you want to do. You should not even try to do what you want to do.
Even if you work out exactly what malloc() is doing, your program would then be relying on undefined behavior. The behavior could change when a new version of the C library arrives, and your program would almost certainly fail if you compiled it using a different toolchain (switch from GNU C to Microsoft C or whatever).
Any time you allocate memory, you need to keep track of the pointer. If your program doesn't even know about the memory, there is no way to free it.
Keep track of your memory allocations. If you are designing data structures to be dynamically allocated, your design should include features to track them, such as keeping a list of addresses in a linked list or something.
If this seems like a lot of work, maybe consider using a managed language like C# or Java or Python or whatever.
free(void*)
[deallocate] A block of memory previously allocated by a call to malloc, calloc or realloc is deallocated, making it available again for further allocations.
If ptr does not point to a block of memory allocated with the above functions, it causes undefined behavior.
- http://www.cplusplus.com/reference/cstdlib/free/
There is no way.
But I can't think of how this can be done
That's because it is not possible. The blocks that you get back from malloc can come in truly arbitrary order. The only way to free a dynamically allocated block of memory is to keep a pointer to it accessible to your program. Anything else is undefined behavior.
Note: Implementations of malloc perform "bookkeeping" to figure out what kind of block you are releasing. While it is not impossible to hack into their implementation, there is no way of doing it in a standard-compliant, portable way.
You cannot create a [-5]...thing for a variety of reasons but the from a practical standpoint you have to remember that memory allocated with malloc() is coming off of the heap and not the stack so to "count" to it from somewhere else is difficult (since multiple calls to malloc are not guaranteed to be sequential).
What happens when a pointer loses its association to memory (or goes out of scope) without being freed is called a memory leak and without exhaustive techniques not readily available in C (Java's mark/sweep garbage collection for example, or mallocing the entire memory and scanning it or something) it is not possible to reclaim this memory.
So you cannot free memory in C when a pointer is not known.
First of all - as it seems you do not understand how malloc works - passing continuous numbers to malloc, won't make it allocate an array. malloc is defined as follows:
void* malloc (size_t size);
While an integer can be converted to size_t, it's still the number of bytes allocated, not the element number. If you want to allocate an array, do it as follows:
int* myDynamicArray = malloc(sizeof(int)*numberOfElements);
Then, you can access the elements by doing:
int i;
for(i=0;i<numberOfElements;i++)
printf("%d",myDynamicArray[i]);
Then, like others pointed out - you can deallocate the memory by calling the free function. free is defined as follows:
void free (void* ptr);
And you simply call it by doing:
free(myDynamicArray);
This is by no means an endorsement of what you have done, but it is possible assuming you know that the blocks were allocated continuously.
For example:
int main(){
char* ptr1=malloc(1);
char* ptr2=malloc(4);
char* ptr3=malloc(5);
// Verify that the memory is in fact continuous.
assert(ptr3==(ptr2+4));
assert(ptr3==(ptr1+5));
free(ptr3); // Frees 5 bytes at ptr3
free(ptr3-4); // Frees 4 bytes at ptr2
free(ptr3-5); // Frees 1 byte at ptr1
}
So, you if you have a pointer and know for a fact that you allocated a set of continuous bytes before it, you can simply offset the pointer with pointer arithmetic. It is highly dangerous and not recommended, but it is possible.
Edit:
I ran a test program and on my architecture, it allocated in 32 byte chunks, so ptr1+32==ptr2, and ptr2+32=ptr3. It did this for any chunks less than or equal to 24 bytes. So if I allocated 24 or less, then each ptr would be 32 bytes greater than the previous. If I allocated 25 or more, then it allocated an additional 16 bytes, making the total 48.
So, in my architecture, you'd need to be much more creative in how you generate your pointers using pointer arithmetic since it will not work as expected.
Here is an example program that works for all sizes of ptr1, ptr2, and ptr3 on my architecture.
#define ROUNDUP(number, multiple) (((number + multiple -1)/multiple)*multiple)
#define OFFSET(size) ((size < 24) ? 32 : ROUNDUP(size+8,16))
int main(int argc, char* argv[]){
char* ptr1, *ptr2, *ptr3;
int s1=atoi(argv[1]);
int s2=atoi(argv[2]);
int s3=atoi(argv[3]);
ptr1=(char*)malloc(s1);
ptr2=(char*)malloc(s2);
ptr3=(char*)malloc(s3);
fprintf(stdout, "%p %p %p\n", ptr1, ptr2, ptr3);
assert(ptr3==(ptr2+OFFSET(s2)));
assert(ptr2==(ptr1+OFFSET(s1)));
// Try to construct ptr2 from ptr3.
free(ptr3);
free(ptr3-OFFSET(s2));
free(ptr3-OFFSET(s2)-OFFSET(s1));
}
From what I understand, the malloc function takes a variable and allocates memory as asked. In this case, it will ask the compiler to prepare memory in order to fit the equivalence of twenty double variables. Is my way of understanding it correctly, and why must it be used?
double *q;
q=(double *)malloc(20*sizeof(double));
for (i=0;i<20; i++)
{
*(q+i)= (double) rand();
}
You don't have to use malloc() when:
The size is known at compile time, as in your example.
You are using C99 or C2011 with VLA (variable length array) support.
Note that malloc() allocates memory at runtime, not at compile time. The compiler is only involved to the extent that it ensures the correct function is called; it is malloc() that does the allocation.
Your example mentions 'equivalence of ten integers'. It is very seldom that 20 double occupy the same space as 10 int. Usually, 10 double will occupy the same space as 20 int (when sizeof(int) == 4 and sizeof(double) == 8, which is a very commonly found setting).
It's used to allocate memory at run-time rather than compile-time. So if your data arrays are based on some sort of input from the user, database, file, etc. then malloc must be used once the desired size is known.
The variable q is a pointer, meaning it stores an address in memory. malloc is asking the system to create a section of memory and return the address of that section of memory, which is stored in q. So q points to the starting location of the memory you requested.
Care must be taken not to alter q unintentionally. For instance, if you did:
q = (double *)malloc(20*sizeof(double));
q = (double *)malloc(10*sizeof(double));
you will lose access to the first section of 20 double's and introduce a memory leak.
When you use malloc you are asking the system "Hey, I want this many bytes of memory" and then he will either say "Sorry, I'm all out" or "Ok! Here is an address to the memory you wanted. Don't lose it".
It's generally a good idea to put big datasets in the heap (where malloc gets your memory from) and a pointer to that memory on the stack (where code execution takes place). This becomes more important on embedded platforms where you have limited memory. You have to decide how you want to divvy up the physical memory between the stack and heap. Too much stack and you can't dynamically allocate much memory. Too little stack and you can function call your way right out of it (also known as a stack overflow :P)
As the others said, malloc is used to allocate memory. It is important to note that malloc will allocate memory from the heap, and thus the memory is persistent until it is free'd. Otherwise, without malloc, declaring something like double vals[20] will allocate memory on the stack. When you exit the function, that memory is popped off of the stack.
So for example, say you are in a function and you don't care about the persistence of values. Then the following would be suitable:
void some_function() {
double vals[20];
for(int i = 0; i < 20; i++) {
vals[i] = (double)rand();
}
}
Now if you have some global structure or something that stores data, that has a lifetime longer than that of just the function, then using malloc to allocate that memory from the heap is required (alternatively, you can declare it as a global variable, and the memory will be preallocated for you).
In you example, you could have declared double q[20]; without the malloc and it would work.
malloc is a standard way to get dynamically allocated memory (malloc is often built above low-level memory acquisition primitives like mmap on Linux).
You want to get dynamically allocated memory resources, notably when the size of the allocated thing (here, your q pointer) depends upon runtime parameters (e.g. depends upon input). The bad alternative would be to allocate all statically, but then the static size of your data is a strong built-in limitation, and you don't like that.
Dynamic resource allocation enables you to run the same program on a cheap tablet (with half a gigabyte of RAM) and an expensive super-computer (with terabytes of RAM). You can allocate different size of data.
Don't forget to test the result of malloc; it can fail by returning NULL. At the very least, code:
int* q = malloc (10*sizeof(int));
if (!q) {
perror("q allocation failed");
exit(EXIT_FAILURE);
};
and always initialize malloc-ed memory (you could prefer using calloc which zeroes the allocated memory).
Don't forget to later free the malloc-ed memory. On Linux, learn about using valgrind. Be scared of memory leaks and dangling pointers. Recognize that the liveness of some data is a non-modular property of the entire program. Read about garbage collection!, and consider perhaps using Boehm's conservative garbage collector (by calling GC_malloc instead of malloc).
You use malloc() to allocate memory dynamically in C. (Allocate the memory at the run time)
You use it because sometimes you don't know how much memory you'll use when you write your program.
You don't have to use it when you know thow many elements the array will hold at compile time.
Another important thing to notice that if you want to return an array from a function, you will want to return an array which was not defined inside the function on the stack. Instead, you'll want to dynamically allocate an array (on the heap) and return a pointer to this block:
int *returnArray(int n)
{
int i;
int *arr = (int *)malloc(sizeof(int) * n);
if (arr == NULL)
{
return NULL;
}
//...
//fill the array or manipulate it
//...
return arr; //return the pointer
}
I've read conflicting information on the internet about this. To the best of my knowledge all variables in a function only exist for the life time of the function and so this shouldn't be necessary. But with dynamic pointer arrays I'm not sure.
Thanks
You don't free pointers - they are cleaned up automatically. What you need to free is the memory that was acquired by malloc. You use pointers to access that memory.
Put laconically: Every pointer you get from malloc has to go to free exactly once. Nothing more, nothing less.
It depends on where the memory referenced by the pointer has been allocated.
There are fundamentally 2 ways of allocating space in C.
Using the stack :
void foo(){
int stack_variable = 10;
int *stack_pointer = &stack_variable; //bar shouldn't be freed.
}
Using the heap:
void foo(){
int * heap_pointer = (int *) malloc(sizeof(int)); //heap_pointer need to be freed somewhere
}
In the first case there is no problem: memory allocated in the stack will be released when the function returns. Even if you are using a pointer, and it points to some data in the stack, free isn't necessary. Be careful to not use a pointer to data allocated in the stack when the data itself goes out of scope:
int * foo(){
int stack_variable = 10;
int *ptr = &stack_variable;
return ptr;
}
int * ptr = foo(); // you have a problem here: ptr points to a memory region that no longer exist!
In the second case you are using the heap so you need to use free somewhere, to explicitly release it.
If you have allocated data using malloc/calloc, you need to free the data.
Addition due to curious comment by #Julia Childe:
Well, the point of allocating dynamic memory is that it will remain there till you explicitly free it. This enables you to pass pointers both from and to functions and you are not limited by the scope of a specific function, i.e. main.
Thereby, you can allocate memory for data when you need to and not in advance, thus dynamic memory.
If we did not have this ability, we would have to know how much memory space we would use at compile time.
Hope this clears out some question marks.