帐前卒专栏

Without software, we are nothing.

Memory Allocation in C

In c language, there are three methods for memory allocation: malloc(), calloc(), realloc(). And one method to free memory: free().

The malloc function prototype is : void* malloc(size_t size); This function will allocates a block of size bytes of memory, returning a pointer to the beginning of the block. Attention: this function is only for allocating memory! So the initial value of these memory will be Non-Zero. Maybe sometimes, it will be zero. Code for example:

1
2
3
4
5
6
7
8
9
10
11
#include<stdio.h>
#include<stdlib.h>
int main(){

  int * a = NULL;
  a = malloc(sizeof(int)*4);
  // like int a[4], but those memory is in heap
  for(int i = 0; i< 4; i++)
      printf("%d ",a[i]);
  return 0;
}

The realloc function prototype is : void realloc(void ptr, size_t size); This function will reallocates a block of size bytes of memory, returning a pointer to the beginning of the block. If size is zero and ptr is not NULL, it will be used as free(). If prt is NULL and size is not zero, it will be used as malloc(). If ptr is NULL and size is zero, return value is some kind of memory which contains zero elements! Wooo~~~~. Look at the following codes:

1
2
3
4
5
6
7
8
char * p = NULL;
printf("%x",(int)p); // will output 0

p = (char*)realloc(p,0);
printf("%x",(int)p); // will output non-zero

p = (char*)realloc(p,0);
printf("%x",(int)p);

why?! Because if this function is called successfully, it will return non-zero memory address. And you will see the third output subtract the second output will be 16 bytes. If ptr is not NULL , and size is non-zero, and current block can simply expand without moving,  the return value is the same as ptr. But there is not enough space for simply expand, it will execute free(ptr) and return malloc(size). This function will become very dangerous!

1
2
3
char * k = (char*)realloc(NULL,100);
char * kbigger = (char*)realloc(k,104);
char * kbiggest = (char*)realloc(k,106); <span style="color: #ff0000;">// crash!</span>

Safety called will be like the following:

1
2
3
char * k = (char*)realloc(NULL,100);
k = (char*)realloc(k,4); // k's address is not changed
k = (char*)realloc(k,104); // k's address is changed

If there is not enough free memory to be allocated, this function will return NULL.Attention: this function will not initialize those memory also.

calloc’s prototype is void* calloc(int num, size_t size).

1
2
3
4
5
6
char* p = (char*)calloc(20,sizeof(char));

// it is equal to

char* p = (char*)malloc(20*sizeof(char));
memset(p,0,20*sizeof(char));

But calloc is efficient!

free function is to delete memory which has been allocated. But free function will not assign the point to zero.

1
2
3
4
5
6
7
8
char * p = (char*)calloc(100);

p[0] = 'a';
printf("%c",p[0]);   // output 'a'
printf("%x",(int)p);
free(p);
printf("%c",p[0]); // output nothing
printf("%x",(int)p); // the value is the same as the first.

And all of those functions will not recommend to be used in c++, because those functions will not initialize class structure or v_ptr. free() function will not destruct parent class when sub class is destructed. In c++, maybe should always use new and delete!

Comments