I have a function in which I make use of a local array. I would like to return a pointer to this, but of course one cannot do this unless one manually allocates memory. Therefore I would like to know if allocation like so:
for(i = 0; i < 26; i++)
{
llist[i] = malloc(sizeof(SomeStruct));
}
can be later freed like so:
// (where ptr is a pointer to the first allocation in llist)
for(i = 0; i < 26, i++)
{
free(ptr);
ptr += sizeof(SomeStruct);
}
Edit:
Seems I can't do this. Is there any way in which I could free all the memory given only a pointer to the first element? Or should I take a different approach entirely?
No, it cannot. There is no guarantee that these blocks are allocated consecutively. In fact, they are almost certainly not with all the modern implementations I've seen. Most store the size of the block and often other information immediately before each block. Also, if your memory is fragmented, the blocks might wind up anywhere in the free space between other data, where there is not sufficient room to place them consecutively.
No, you can't. In the first empty space malloc finds it might only be place for one struct. If that's the case, the next block will be placed somewhere else.
Depends on what you do inside the loop. Some functions will allocate buffers internally, which means that malloc() could be called behind your back. In your simple loop, the values SHOULD be consecutive. As well, once you throw in multi-threading, all bets are out the window, as something in another thread could malloc() memory as well.
The actual allocation spot also depends on how fragmented your memory is. There may not be enough consecutive blocks to handle your request, so the actual allocation could be from anywhere in the free space.
Related
I'm just starting to learn coding in c, and I have a few questions regarding 2d matrices in combination with the free() command.
I know that you first need to create an array with pointer, pointing to the different columns of the matrix:
double **array = (double **)malloc(5*sizeof(double *));
for(int n = 0; n<5; n++){
array[n] = (double *) malloc(6*sizeof(double));
I know that the correct way to then deallocate this matrix is to first deallocate the individual rows and then the array pointer itself. Something along the lines of:
for (i = 0; i < nX; i++){
free(array[i]); }
free(array);
My question is: Why is this necessary? I know that this incorrect, but why can't you just use: free(array)? This would deallocate the pointer array, to my understanding. Won't the memory that is used by the columns just be overwritten when something else needs acces to it? Would free(array) lead to corrupted memory in any way?
Any help is much appreciated!
Your code, not only allocate memory for array of pointers (the blue array), but in the for loop, you also allocate memory for the red arrays as well. So, free(array) line, alone, will just free the memory allocated by the blue array, but not the red ones. You need to free the red ones, just before loosing the contact with them; that is, before freeing the blue array.
And btw;
Won't the memory that is used by the columns just be overwritten when something else needs acces to it?
No. The operating system will keep track of the memory allocated by your process (program) and will not allow any other process to access the allocated memory until your process terminates. Under normal circumstances —I mean, remembering the C language not having a garbage collector— the OS never knows that you've lost connection with the allocated memory space and will never attempt like, "well, this memory space is not useful for this process anymore; so, let's de-allocate it and serve it for another process."
It would not lead to corruption, no, but would create a memory leak.
If done once in your program, it probably doesn't matter much (a lot of professional/expensive applications have - small,unintentional - memory leaks), but repeat this in a loop, and you may run out of memory after a while. Same thing if your code is called from an external program (if your code is in a library).
Aside: Not freeing buffers can be a useful way (temporarily) to check if the crashes you're getting in your programs originate from corrupt memory allocation or deallocation (when you cannot use Valgrind). But in the end you want to free everything, once.
If you want to perform only one malloc, you could also allocate one big chunk, then compute the addresses of the rows. In the end, just deallocate the big chunk (example here: How do we allocate a 2-D array using One malloc statement)
This is needed because C does not have a garbage collector.
Once you allocate memory with malloc or similar function, it is marked as "in use" for as long as your program is running.
It does not matter if you no longer hold a pointer to this memory in your program.
There is no mechanism in the C language to check this and automatically free the memory.
Also, when you allocate memory with malloc the function does not know what you are using the memory for. For the allocator it is all just bytes.
So when you free a pointer (or array of pointers), there is no logic to "realize" these are pointers that contain memory addresses.
This is simply how the C language is designed: the dynamic memory management is almost1 completely manual - left to the programmer, so you must call free for every call to malloc.
1 C language does handle some of the more tedious tasks needed to dynamically allocate memory in a program such as finding where to get a free continuous chunk of memory of the size you asked for.
Let's take this simple example:
int **ptr = malloc(2*sizeof *ptr);
int *foo = malloc(sizeof *foo);
int *bar = malloc(sizeof *bar);
ptr[0] = foo;
ptr[1] = bar;
free(ptr);
If your suggestion were implemented, foo and bar would now be dangling pointers. How would you solve the scenario if you just want to free ptr?
Let's suppose I have this code:
for (int i=0;i<n;i++) {
//compute z
float *p = (float *) malloc (sizeof(float)*z);
//do something with p
}
Notice that p isn't used anywhere else and each for cycle is independent from the other.
Let's suppose that z is not so big, so the single p is not that expensive in terms of memmory. However, n is potentially big, so the total memory taken by p can be consistent.
Is it correct to free() it with:
for (int i=0;i<n;i++) {
//compute z
float *p = (float *) malloc (sizeof(float)*z);
//do something with p
free(p);
}
Bonus question: if time performance would be the priority (and not memory consumption), would be better to avoid the free(p), since it's time consuming?
Since you tagged this with C++, you should never use malloc and free. Use smart pointers (or new/delete if you don't have access to a C++11-compliant compiler).
for (int i=0;i<n;i++) {
// compute z
std::unique_ptr<float[]> p{new float[z]};
// do something with p
// p gets automatically freed at the end of the scope
}
To answer your questions:
Is it correct to free() it with...
Yes. If you allocate something with malloc, you always need to free it.
would be better to avoid the free(p), since it's time consuming?
Yes. Consider preallocating the memory location outside of the loop.
// preallocate
std::unique_ptr<float[]> p{new float[z]};
for (int i=0;i<n;i++) {
// clear p
// compute z
// do something with p
}
// p gets automatically freed at the end of the scope
You can pre-allocate necessary memory amount before the cycle and re-use it.
In case if you don't know how big z would be - I would recommend to write size of allocated memory somewhere, and if z is bigger than it - then re-allocate, else - just re-use already allocated memory.
Observe: malloc is used. Act: invoke free. It's as simple as that. Portable, well-defined code requires malloc and free.
The amount of memory allocated plays no role here. If it's too much memory, malloc will throw an error, but that has nothing to do with the fact that you always need a free to follow a malloc.
Yes. You must free it. Otherwise you have a memory leak, which is bad. Especially if you loop a large number of times.
A good rule of thumb is that every malloc must be matched by a free. Always. (this is especially important on larger projects)
Consider using a buffer, that is reused in order to avoid unnecessary allocations. This can be done very easily by using std::vector<float>:
std::vector<float> p;
for (int i=0;i<n;i++) {
//compute z
p.resize( z );
//do something with p
}
In the worst case you get O(log n) memory allocations. With your code you will get n memory allocations. Not calling free() just causes a memory leak. std::vector<float> will clean up the memory automatically eventually.
It seems the size is constant, so why you want to allocate it again and again?
Just allocate once before the loop, inside the loop initialise at the beginning.
You can reuse the memory. And after the loop ends free the memory.
And the program ends after the loop then you don't have to free it, all the heap memory that the program consumed would be returned to the OS, but it is always a good practice to free the memory you allocate.
On the bonus question, free is not that time consuming but allocating memory is, so don't worry on the time consumed by free.
If you reuse that memory again - it is obviously more efficient to free it only when you end your program and only allocated it once (and reallocate using realloc() when you need bigger/smaller array).
Every OS you will probably program for will handle releasing dynamically allocated memory when your program terminates. But, as we mostly try to keep our code as cross-platform as possible, you should always free() dynamically allocated memory.
As for if you have a huge amount of memory and care only for speed - then obviously free()ing would 'slow down' the program, but the amount of time it takes is so ridiculously small, 76*(10**-8) on my humble machine, for a 1024 bytes chunk, so it is fairly insignificant.
I am confused on what actually happens in memory when memset is called versus what happens when you call free.
For example I have a pointer A that points to an array of char*'s
char** A = (char**)calloc(5, sizeof(char*));
int i;
for(i=0;i<5;i++)
{
//filling
A[i] = (char*)calloc(30, sizeof(char));
scanf("%s", &A[i]);
}
now I want to reset it my char** pointer and all the elements
it points to be completely empty
memset(A, 0, 5);
or
free(A);
what is the difference?
I am somewhat new to C so please speak in layman's terms thank you
The difference is that memset actually sets the value of a block of memory, while free returns the memory for use by the operating system.
By analogy using physical things, memset(beer, 0, 6) applied to a six-pack of beer would apply the value of '0' to all six members of the array beer, while free(beer) would be the equivalent of giving the six-pack away to a friend.
The memset function sets an area of memory to the requested value. Do note that the size you provide is the number of bytes.
The free function releases the allocated memory so it can't be used anymore. Calling free doesn't usually modify the memory in any way. Using the memory after calling free leads to undefined behavior.
Both approaches are incorrect, but somewhat complementary.
memset will set the content of the buffer to the given value, 0 in your case. This will change the value of the pointers, which will cause you to lose the references to the allocated buffers (in each A[i]).
free(A) will release the buffer pointed by A, but this buffer contains pointers, and each of the buffers that is pointed by them will not be freed.
in short - memset does not free a dynamically allocated buffer, and free does not set it to zero.
A correct approach will be something like that:
for(i=0;i<5;i++)
{
// complementary to
// A[i] = (char*)calloc(30, sizeof(char));
free(A[i]);
}
// complementary to
// char** A = (char**)calloc(5, sizeof(char*));
free(A);
A = NULL; // so no one gets confused...
free deallocates the memory, which means A would still be pointing to the same memory location, which is invalid now.
memset will set the memory currently pointed to by A, to whatever you want.
memset changes the contents at the memory address. It does not alter whether the memory is allocated/deallocated.
free does not change the contents at the memory address. It deallocates the block of memory which makes it available for the program to reclaim and reuse. Therefore any pointers to this block become invalid and trying to access the memory should result in a Segfault ("if you're lucky" as my professor would say).
Use memset when you know you are going to be accessing the data at that address again. Use free when you know that the data will no longer be accessed ever again and that the program may reclaim that memory.
memset() method just replaces the x memory bytes with a given character the allocated memory which is pointed by a pointer *a;
memset(a, 'a', x);
The prototype of memset() method is:
void* memset(void*, unsigned int, int);
memset() behaves like strcpy() but the difference is that memcpy() copied the data as it is (byte), but strcpy copies the formatted string as well (so takes more time than memcpy to execute).
However, free() method just deallocates the memory space and makes it available to get occupied.
While other answers explain the difference, let me add an example when both memset() and free() will need to be used together, in a specific order:
If the malloc'ed memory region was used to store any critical/valuable information that needs to be erased to prevent others from snooping on it (say some security-related stuff like managing a password or some other crypto), you would want to first erase the contents in that memory region and then call free() on it to give away that region's control back to the OS.
Hence, just like free() is the opposite of malloc(), memset(to zero)-then-free() is the opposite of calloc().
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
}
Here is what I am working with:
char* qdat[][NUMTBLCOLS];
char** tdat[];
char* ptr_web_data;
// Loop thru each table row of the query result set
for(row_index = 0; row_index < number_rows; row_index++)
{
// Loop thru each column of the query result set and extract the data
for(col_index = 0; col_index < number_cols; col_index++)
{
ptr_web_data = (char*) malloc((strlen(Data) + 1) * sizeof(char));
memcpy (ptr_web_data, column_text, strlen(column_text) + 1);
qdat[row_index][web_data_index] = ptr_web_data;
}
}
tdat[row_index] = qdat[col_index];
After the data is used, the memory allocated is released one at a time using free().
for(row_index = 0; row_index < number_rows; row_index++)
{
// Loop thru all columns used
for(col_index = 0; col_index < SARWEBTBLCOLS; col_index++)
{
// Free memory block pointed to by results set array
free(tdat[row_index][col_index]);
}
}
Is there a way to release all the allocated memory at once, for this array?
Thank You.
Not with the standard malloc() allocator - you need to investigate the use of memory pools. These work by allocating a big block of memory up-front, allocating from it and freeing back to it as you request via their own allocation functions, and then freeing the whole lot with a special "deallocate all" function.
I must say I've always found these things a bit ugly - it really isn't that hard to write code that doesn't leak. The only reason I can see for using them is to mitigate heap fragmentation, if that is a real problem for you.
No there is not. Memory which is separately allocated must be separately freed.
The only way you could free it as once is if you allocated it at once is a giant block. You would then have to do a bit of pointer math to assign every row the correct index into the array but it's not terribly difficult. This approach does have a few downsides though
Extra pointer math
Requires one giant contiguous block of memory vs. N smaller blocks of memory. Can be an issue in low memory or high fragmentation environments.
Extra work for no real stated gain.
If you want to release it all at once, you have to allocate it all at once.
A simple manual solution, if you know the total size you'll need in advance, is to allocate it all in once chunk and index into it as appropriate. If you don't know the size in advance you can use realloc to grow the memory, so long as you only access it indexed from the initial pointer, and don't store additional pointers anywhere.
That being said, direct allocation and deallocation is a simple solution, and harder to get wrong than the alternatives. Unless the loop to deallocate is causing you real difficulties, I would stick with what you have.