Dynamic memory allocation in for loop - c

I'm allocating memory using malloc:
main()
{
int *array;
int i;
for(i = 0; i<40; i++)
{
array = malloc(100 * sizeof(int));
}
free(array);
}
This should allocate 15.625KB but if i run this same in valgrind, peak memory is 15.92KB. How it comes?
How to free all 40 pointers?

malloc always allocates a bit more than you asked for, necessary for internal accounting, caused by fragmentation, etc.
At a minimum - the size of each allocated block need to be stored somewhere, often some pointers (e.g. to the next allocated/free block) are also stored, and in some cases (e.g. debug builds) additional debugging information is also stored. Most implementation store as much information as possible in the unallocated space, so only a few bytes (e.g. size) would be stored in each allocated block.
As to fragmentation, many implementations have a minimal allocated size or round up the requested size to maintain some kind of alignment.

Regarding freeing all 40 pointers, you could for example have an array of pointers holding the pointers returned from malloc and go over it at the end of your function.
Something along the lines of:
main()
{
int *arrays[40];
int i;
for(i = 0; i<40; i++)
{
arrays[i]=malloc(100 * sizeof(int));
}
for(i = 0; i<40; i++)
{
free(arrays[i]);
}
}

free (array) should be inside the loop to free all pointers instead of the last one only.

When you call malloc(),The amount of memory actually used is slightly more than what is requested.This extra includes information that records how big the block is, where is next free block available etc.
This extra information is the reason so that free() function knows how much to free.

Related

How to use or free dynamically allocated memory when I run the program multiple times?

How do I free dynamically allocated memory?
Suppose input (assume it is given by user) is 1000 and now if I allocate memory of 1000 and after this(second time) if user gives input as 500 can I reuse already allocated memory ?
If user now inputs value as say 3000 , how do I go with it ? can I reuse already allocated 1000 blocks of memory and then create another 2000 blocks of memory ? or should I create all 3000 blocks of memory ?
which of these is advisable?
#include <stdio.h>
#include <stdlib.h>
typedef struct a
{
int a;
int b;
}aa;
aa* ptr=NULL;
int main() {
//code
int input=2;
ptr=malloc(sizeof(aa)*input);
for(int i=0;i<input;i++)
{
ptr[i].a=10;
ptr[i].b=20;
}
for(int i=0;i<input;i++)
{
printf("%d %d\n",ptr[i].a,ptr[i].b);
}
return 0;
}
I believe, you need to read about the "lifetime" of allocated memory.
For allocator functions, like malloc() and family, (quoting from C11, chapter §7.22.3, for "Memory management functions")
[...] The lifetime of an allocated object extends from the allocation
until the deallocation. [....]
So, once allocated, the returned pointer to the memory remains valid until it is deallocated. There are two ways it can be deallocated
Using a call to free() inside the program
Once the program terminates.
So, the allocated memory is available, from the point of allocation, to the termination of the program, or the free() call, whichever is earlier.
As it stands, there can be two aspects, let me clarify.
Scenario 1:
You allocate memory (size M)
You use the memory
You want the allocated memory to be re-sized (expanded/ shrinked)
You use some more
You're done using
is this is the flow you expect, you can use realloc() to resize the allocated memory size. Once you're done, use free().
Scenario 2:
You allocate memory (size M)
You use the memory
You're done using
If this is the case, once you're done, use free().
Note: In both the cases, if the program is run multiple times, there is no connection between or among the allocation happening in each individual invocation. They are independent.
When you use dynamically allocated memory, and adjust its size, it is important to keep track of exactly how many elements you have allocated memory for.
I personally like to keep the number of elements in use in variable named used, and the number of elements I have allocated memory for in size. For example, I might create a structure for describing one-dimensional arrays of doubles:
typedef struct {
size_t size; /* Number of doubles allocated for */
size_t used; /* Number of doubles in use */
double *data; /* Dynamically allocated array */
} double_array;
#define DOUBLE_ARRAY_INIT { 0, 0, NULL }
I like to explicitly initialize my dynamically allocated memory pointers to NULL, and their respective sizes to zero, so that I only need to use realloc(). This works, because realloc(NULL, size) is exactly equivalent to malloc(NULL). I also often utilize the fact that free(NULL) is safe, and does nothing.
I would probably write a couple of helper functions. Perhaps a function that ensures there is room for at_least entries in the array:
void double_array_resize(double_array *ref, size_t at_least)
{
if (ref->size < at_least) {
void *temp;
temp = realloc(ref->data, at_least * sizeof ref->data[0]);
if (!temp) {
fprintf(stderr, "double_array_resize(): Out of memory (%zu doubles).\n", at_least);
exit(EXIT_FAILURE);
}
ref->data = temp;
ref->size = at_least;
}
/* We could also shrink the array if
at_least < ref->size, but usually
this is not needed/useful/desirable. */
}
I would definitely write a helper function that not only frees the memory used, but also updates the fields to reflect that, so that it is completely safe to call double_array_resize() after freeing:
void double_array_free(double_array *ref)
{
if (ref) {
free(ref->data);
ref->size = 0;
ref->used = 0;
ref->data = NULL;
}
}
Here is how a program might use the above.
int main(void)
{
double_array stuff = DOUBLE_ARRAY_INIT;
/* ... Code and variables omitted ... */
if (some_condition) {
double_array_resize(&stuff, 321);
/* stuff.data[0] through stuff.data[320]
are now accessible (dynamically allocated) */
}
/* ... Code and variables omitted ... */
if (weird_condition) {
/* For some reason, we want to discard the
possibly dynamically allocated buffer */
double_array_free(&stuff);
}
/* ... Code and variables omitted ... */
if (other_condition) {
double_array_resize(&stuff, 48361242);
/* stuff.data[0] through stuff.data[48361241]
are now accessible. */
}
double_array_free(&stuff);
return EXIT_SUCCESS;
}
If I wanted to use the double_array as a stack, I might do
void double_array_clear(double_array *ref)
{
if (ref)
ref->used = 0;
}
void double_array_push(double_array *ref, const double val)
{
if (ref->used >= ref->size) {
/* Allocate, say, room for 100 more! */
double_array_resize(ref, ref->used + 100);
}
ref->data[ref->used++] = val;
}
double double_array_pop(double_array *ref, const double errorval)
{
if (ref->used > 0)
return ref->data[--ref->used];
else
return errorval; /* Stack was empty! */
}
The above double_array_push() reallocates for 100 more doubles, whenever the array runs out of room. However, if you pushed millions of doubles, this would mean tens of thousands of realloc() calls, which is usually considered wasteful. Instead, we usually apply a reallocation policy, that grows the size proportionally to the existing size.
My preferred policy is something like (pseudocode)
If (elements in use) < LIMIT_1 Then
Resize to LIMIT_1
Else If (elements in use) < LIMIT_2 Then
Resize to (elements in use) * FACTOR
Else
Resize to (elements in use) + LIMIT_2
End If
The LIMIT_1 is typically a small number, the minimum size ever allocated. LIMIT_2 is typically a large number, something like 220 (two million plus change), so that at most LIMIT_2 unused elements are ever allocated. FACTOR is between 1 and 2; many suggest 2, but I prefer 3/2.
The goal of the policy is to keep the number of realloc() calls at an acceptable (unnoticeable) level, while keeping the amount of allocated but unused memory low.
The final note is that you should only try to keep around a dynamically allocated buffer, if you reuse it for the same (or very similar) purpose. If you need an array of a different type, and don't need the earlier one, just free() the earlier one, and malloc() a new one (or let realloc() in the helpers do it). The C library will try to reuse the same memory anyway.
On current desktop machines, something like a hundred or a thousand malloc() or realloc() calls is probably unnoticeable compared to the start-up time of the program. So, it is not that important to minimize the number of those calls. What you want to do, is keep your code easily maintained and adapted, so logical reuse and variable and type names are important.
The most typical case where I reuse a buffer, is when I read text input line by line. I use the POSIX.1 getline() function to do so:
char *line = NULL;
size_t size = 0;
ssize_t len; /* Not 'used' in this particular case! :) */
while (1) {
len = getline(&line, &size, stdin);
if (len < 1)
break;
/* Have 'len' chars in 'line'; may contain '\0'! */
}
if (ferror(stdin)) {
fprintf(stderr, "Error reading standard input!\n");
exit(EXIT_FAILURE);
}
/* Since the line buffer is no longer needed, free it. */
free(line);
line = NULL;
size = 0;

Why is memory size doubled when allocating a large number of char*?

I allocate a 2D array of char * and every string length is 12.
50 rows and 2000000 columns.
Lets calculate it:
50*2000000 * (12(length)+8(for pointer)). I use 64 bit.
50*2000000 * 20 =2000000000 bits .. -> 2 GB.
When I check the memory monitor it shows that the process takes 4 GB.
(All that happened after allocation)
This is the code:
int col=2000000,row=50,i=0,j=0;
char *** arr;
arr=(char***)malloc(sizeof(char**)*row);
for(i=0;i<row;i++)
{
arr[i]=(char ** )malloc(sizeof(char*)*col);
for(j=0;j<col;j++)
{
arr[i][j]=(char*)malloc(12);
strcpy(arr[i][j],"12345678901");
arr[i][j][11]='\0';
}
}
May that be from the paging in Linux?
Each call of malloc is taking more memory than you ask. Malloc needs to store somewhere its internal info about allocated place, like size of allocated space, some info about neighbors chunks, etc. Also (very probably) each returned pointer is aligned to 16 bytes. In my estimation each allocation of 12 bytes takes 32 bytes of memory. If you want to save memory allocate all strings in one malloc and split them into sizes per 12 at your own.
Try the following:
int col=2000000,row=50,i=0,j=0;
char *** arr;
arr= malloc(sizeof(*arr)*row);
for(i=0;i<row;i++)
{
arr[i]= malloc(sizeof(*arr[i])*col);
char *colmem = malloc(12 * col);
for(j=0;j<col;j++)
{
arr[i][j] = colmem + j*12;
strcpy(arr[i][j],"12345678901");
}
}
I would re-write the code from scratch. For some reason, around 99% of all C programmers don't know how to correctly allocate true 2D arrays dynamically. I'm not even sure I'm one of the 1% who do, but lets give it a shot:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main()
{
const int COL_N = 2000000;
const int ROW_N = 50;
char (*arr)[ROW_N] = malloc( sizeof(char[COL_N][ROW_N]) );
if(arr == NULL)
{
printf("Out of memory");
return 0;
}
for(int row=0; row<ROW_N; row++)
{
strcpy(arr[row], "12345678901");
puts(arr[row]);
}
free(arr);
return 0;
}
The important parts here are:
You should always allocate multi-dimensional arrays in adjacent memory cells or they are not arrays, but rather pointer-based lookup tables. Thus you only need one single malloc call.
This should save a bit of memory since you only need one pointer and it is allocated on the stack. No pointers are allocated on the heap.
Casting the return value of malloc is pointless (but not dangerous on modern compilers).
Ensure that malloc actually worked, particularly when allocating ridiculous amounts of memory.
strcpy copies the null termination, you don't need to do it manually.
There is no need for nested loops. You want to allocate a 2D array, not a 3D one.
Always clean up your own mess with free(), even though the OS might do it for you.

char pointer is struct array memory leak

I'm having memory leaks in a larger program and I believe this is the cause of it.
#include <stdlib.h>
#include <Windows.h>
typedef struct _struct{
char* name;
} str;
int main() {
system("PAUSE");
str* Character = (str*)malloc(sizeof(str) * 20000);
for(int i = 0; i < 20000; i++){
Character[i].name = (char*)malloc(20000); // Assign memory.
}
for(int i = 0; i < 20000; i++){
free(Character[i].name); // Free memory.
}
free(Character);
system("PAUSE");
}
Memory at first pause: ~500K.
Memory at second pause: ~1.7M.
Using VS2012 for testing. Any ideas?
How are you measuring the amount of memory occupied by the program? One thing off the top of my head is that you're looking at the size of the working set the OS is keeping track of. Since you've allocated and freed a lot of memory, the size of that set has increased. Some OSs will adjust the size of the working set after a while, some won't. What OS are we looking at here?
When you call malloc, memory is allocated on the heap. If there is insufficient space left on the heap, the program will ask the OS for more memory and another chunk is acquired. Memory acquired from the OS is usually not returned until the program finishes (although this is up to the OS).
Program size alone can not normally be used to check for memory leaks! Use Valgrind or a similar tool to check for memory that never gets freed.
str* Character = (str*)malloc(sizeof(str) * 20000);
In the above line you are allocating the memory by finding the size of the struct. Here the size of the structure you will get will be the size of the pointer width and not the size of the char.
suppose for example if the pointer width is 32 bit the it will allocate (4 * 20000) = 80000 bytes.
If you want to allocate for 20000 struct's,
str* Character = (str*)malloc(sizeof(char) * 20000);

memory leak (free function not working)

I am facing memory leak problem with the below code
static char **edits1(char *word)
{
int next_idx;
char **array = malloc(edits1_rows(word) * sizeof (char *));
if (!array)
return NULL;
next_idx = deletion(word, array, 0);
next_idx += transposition(word, array, next_idx);
next_idx += alteration(word, array, next_idx);
insertion(word, array, next_idx);
return array;
}
static void array_cleanup(char **array, int rows) {
int i;
for (i = 0; i < rows; i++)
free(array[i]);
}
static char *correct(char *word,int *count) {
char **e1, **e2, *e1_word, *e2_word, *res_word = word;
int e1_rows, e2_rows,max_size;
e1_rows = edits1_rows(word);
if (e1_rows) {
e1 = edits1(word);
*count=(*count)*300;
e1_word = max(e1, e1_rows,*count);
if (e1_word) {
array_cleanup(e1, e1_rows);
free(e1);
return e1_word;
}
}
*count=(*count)/300;
if((*count>5000)||(strlen(word)<=4))
return res_word;
e2 = known_edits2(e1, e1_rows, &e2_rows);
if (e2_rows) {
*count=(*count)*3000;
e2_word = max(e2, e2_rows,*count);
if (e2_word)
res_word = e2_word;
}
array_cleanup(e1, e1_rows);
array_cleanup(e2, e2_rows);
free(e1);
free(e2);
return res_word;
}
I don’t know why free() is not working. I am calling this function "correct" in thread, multiple threads are running simultaneously.I am using Ubuntu OS.
You don't show where you allocate the actual arrays, you just show where you allocate the array of pointers. So it is quite possible that you have leaks elsewhere in the code you are not showing.
Furthermore, array_cleanup leaks since it only deletes those arrays you don't show where you allocate. It doesn't delete the array of pointers itself. The final row of that function should have been free(array);.
Your main problem is that you are using an obscure allocation algorithm. Instead, allocate true dynamic 2D arrays.
Answer based on digging for further information in comments.
Most malloc implementations usually don't return the memory to the operating system, but rather keep it for future calls to malloc. This is done because returning the memory to the operating system can impact performance quite a lot.
Furthermore, if you have certain allocation patterns, the memory that malloc keeps might not be easily reusable by future calls to malloc. This is called memory fragmentation and is a large topic of research for designing memory allocators.
Whatever htop/top/ps reports is not how much memory you have currently allocated inside your program with malloc, but all the various allocations that all libraries did, their reserves and such, which could be much more than you've allocated.
If you want an accurate assessment of how much memory you are leaking, you need to use a tool like valgrind or see if maybe the malloc you're using has diagnostic tools to help you with that.

defining a global struct pointer in C?

I need to identify a global struct (array), consisted of 4 integers.
The problem is, size of that struct array is not known in advance.
I'm trying to make sth. like this:
typedef struct
{
int value;
int MAXleft;
int MAXright;
int MAX;
} strnum;
int main ()
{
int size;
scanf("%d", &size);
strnum numbers[size];
return 0;
}
I heard that, it is possible to do this by pointers but I don't know how to do.
You can allocate the space for several structures dynamically like this:
strnum *numbers = malloc( size * sizeof(strnum) );
Then you can use it like any regular array (mostly).
It might be more convenient to use calloc instead of malloc. It allocates a number of blocks and fills them with zeros. Please note, that malloc doesn't clear allocated memory.
strnum *numbers = calloc( size, sizeof(strnum) );
When you are done with the memory don't forget to call free( numbers ), which will return the allocated memory back to a memory manager.
If you don't free it when it's no longer required and allocate some more and more, a memory footprint of the program will grow for no good reason as the program continues to work. This is called a memory leak and should be avoided. It might eventually result in the lack of memory for a program and unpredictable results.
And don't forget to include a stdlib.h header with prototypes of memory allocation functions.
You can start with malloc() and then do realloc() when the size keeps increasing.
I would suggest you to allocate a pool of 10 structures at once so that the number of calls to realloc() are reduced.
It is called Dynamic Memory Allocation
The thing you are trying to do can be done as follows:
strnum* number;
int size = 0;
scanf("%d",&size);
number = malloc(size * sizeof(strnum));
Also, don't forget to free the memory once you have done using the array.
free(number);

Resources