Complete guide on stdlib.h in C


<stdlib.h> is the header for the General Purpose Standard Library of C programming language which declares a variety of utility functions for type conversions, memory allocation, process control and other similar tasks. It also has multiple data types and macros defined in the header.

To use this header in C, you have to type the following line at the top of your C program:

#include <stdlib.h>

The #include <x/*y> specifies inclusion of a system header file named x/*y.
This header can also be used in C++ by using cstdlib.
In this page, we will be describing all the functions, data types and macros defined in stdlib.h.

The Functions defined:

As mentioned earlier, there are more than 20 functions defined in this header. Below we have explained each and every function in detail.

For Type conversion:

1. double atof(const char *s)

This function converts the string s to a floating-point number of type double and returns it. It is equivalent to strtod(s,(char**)NULL).
If no valid conversion can be made, it returns 0.0.

You can refer to the below code snippet to understand its implementation.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
   float value;
   char str[20];   
   strcpy(str, "12345678");
   value = atof(str);
   printf("String = %s, Float value = %f\n", str, value);

   strcpy(str, "opengenus.org");
   value = atof(str);
   printf("String = %s, Float value = %f\n", str, value);

   return(0);
}

On compiling the above program, we would get this result:

String = 12345678, Float value = 12345678.000000
String = opengenus.org, Float value = 0.000000

2. int atoi(const char *s)

This function converts a string s to an integer i.e int and returns it. It is equivalent to (int)strtol(s,(char**)NULL, 10).
If no valid conversions can be made for the given string, it then returns zero.
You can refer to the below code to understand its implementation:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
   int value;
   char strs[20];   
   strcpy(strs, "12345678");
   value = atoi(strs);
   printf("String = %s, Int value = %d\n", strs, value);
   strcpy(str, "opengenus.org");
   value = atoi(strs);
   printf("String = %s, Int value = %d\n", strs, value);
   return(0);
}

On compiling the above program, we would get this result:

String = 12345678, Int value = 12345678
String = opengenus.org, Int value = 0

3. long atol(const char *s)

This function converts a string s to an long integer (data type: long) and returns it. It is equivalent to strtol(s,(char**)NULL, 10).
If no valid conversions can be made for the given string, it then returns zero.
You can refer to the below code to understand its implementation:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
   long val;
   char str[20];   
   strcpy(str, "12345678");
   val = atol(str);
   printf("String value = %s, Long value = %ld\n", str, val);
   strcpy(str, "opengenus.org");
   val = atol(str);
   printf("String value = %s, Long value = %ld\n", str, val);
   return(0);
}

On compiling the above program, we would get this result:

String value = 12345678, Long value = 12345678
String value = opengenus.org, Long value = 0

4. double strtod(const char *s, char **endp)

The function strtod converts the prefix of s to double, ignoring the leading whitespace. It stores a pointer to any unconverted suffix in *endp unless it is NULL.
If the answer would overflow, HUGE_VAL is returned with the proper sign. If the answer would underflow, zero is returned. In either case errno is set to ERANGE.
You can refer to the below code to understand its implementation:

#include <stdio.h>
#include <stdlib.h>
int main () { 
   char str[30] = "21.32322 This is the text";
   char *ptr;
   double ret;
   ret = strtod(str, &ptr);
   printf("The number(double) is %lf\n", ret);
   printf("String part is |%s|", ptr);
   return(0);
}

On compiling the above program, we would get this result:

The number(double) is 21.323220
String part is | This is the text|

You can notice that the white space in between the number and the text is also included in the string ptr. Also note the extra zero at the end of the number, this is because the data type is a double.

5. long strtol(const char *s, char **endp, int base)

The function strtol converts the prefix of string s to long, ignoring leading whitespace. It stores a pointer to any unconverted suffix in endp unless endp is NULL.
If base is between 2 and 36, conversion is done assuming that the input is written in that base. If base is zero, the base is 8, 10, or 16. Leading 0 implies octal and leading 0x or 0X hexadecimal. Letters in either case represent digits from 10 to base-1. A leading 0x or 0X is permitted in base 16.
If you didn't understand what the above meant, just ignore it. You would most likely be needing only base 10.
If the answer would overflow, LONG_MAX or LONG_MIN is returned, depending in the sign of the result, and errno is set to ERANGE.
You can refer to the below code to understand its implementation.

#include <stdio.h>
#include <stdlib.h>
int main () {
   char str[30] = "2020200 This is the text";
   char *ptr;
   long ret;
   ret = strtol(str, &ptr, 10);
   printf("The number (long integer) is %ld\n", ret);
   printf("String part is |%s|", ptr);
   return(0);
}

On compiling the above program, we would get this result:

The number (long integer) is 2020200
String part is | This is the text|

6. unsigned long strtoul(const char *s, char **endp, int base)

The function strtoul is the same as strtol except that the result is unsigned long and the error value is ULONG_MAX.

#include <stdio.h>
#include <stdlib.h>
int main () {
   char str[30] = "2030300 This is the text part";
   char *ptr;
   unsigned long ret;
   ret = strtoul(str, &ptr, 10);
   printf("The number(unsigned long integer) is %lu\n", ret);
   printf("String part is |%s|", ptr);
   return(0);
}

On compiling the above program, we would get this result:

The number(unsigned long integer) is 2030300
String part is | This is the text part|

For Pseudo-random Sequence Generation:

1. int rand(void)

The function rand returns a pseudo-random in the range 0 to RAND_MAX, which is at least 32767.
PS: Never use rand() for security purposes.

#include <time.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
	srand(time(NULL));   // Initialization, should only be called once.
	//Please refer to the next topic to understand the above function.
	int r = rand();      // Returns a pseudo-random integer between 0 and RAND_MAX.
	printf("The random number is: %d", r);
}

On compiling the above program, we would get this result:

The random number is: 16426

2. void srand(unsigned int seed)

The function srand uses seed as the seed for a new sequence of pseudo-random numbers. The initial seed is 1.
The folowing code shows the use of the srand function:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main () {
   int i, n;
   time_t t;   
   n = 5;
   /* Intializes random number generator */
   srand((unsigned) time(&t));
   /* Print 5 random numbers from 0 to 50 */
   for( i = 0 ; i < n ; i++ ) {
      printf("%d\n", rand() % 50);
   }
   return(0);
}

The output of the above code is:

38
45
29
29
47

For Memory Allocation And Deallocation:

1. void *calloc(size_t nobj, size_t size)

The function calloc returns a pointer to a space for an array of nobj objects, each of size size, or NULL if the request cannot be satisfied. The space is initialized to zero bytes. For integers, the initial value is set to 0.
The below code shows the working of the above function:

#include <stdio.h>
#include <stdlib.h>
int main () {
   int i, n;
   int *a;
   printf("Number of elements to be entered:");
   scanf("%d",&n);
   a = (int*)calloc(n, sizeof(int));
   printf("Enter %d numbers:\n",n);
   for( i=0 ; i < n ; i++ ) {
      scanf("%d",&a[i]);
   }
   printf("The numbers entered are: ");
   for( i=0 ; i < n ; i++ ) {
      printf("%d ",a[i]);
   }
   free( a );//This is a very good practice. Explained below.
   return(0);
}

The output we get on running the above code is:

Number of elements to be entered:3
Enter 3 numbers:
12
23
34
The numbers entered are: 12 23 34

2. void *malloc(size_t size)

The function malloc returns a pointer to a space for an object of size size, or NULL if the request cannot be satisfied. The space is uninitialized.
If you try to access the values, you could either get an error or a garbage value.

#include <stdio.h> 
#include <stdlib.h> 
int main() 
{ 
	int* ptr; 
	int n, i; 
	n = 5; //Number of elements
	printf("Enter number of elements: %d\n", n); 
	ptr = (int*)malloc(n * sizeof(int)); 
	if (ptr == NULL) { 
		printf("Memory not allocated.\n"); //Space is not sufficient.
		exit(0); 
	} 
	else { 
		printf("Memory successfully allocated using malloc.\n");
		for (i = 0; i < n; ++i) { 
			ptr[i] = i + 1; 
		}
		printf("The elements of the array are: "); 
		for (i = 0; i < n; ++i) { 
			printf("%d, ", ptr[i]); 
		} 
	} 
    return 0; 
} 

The output of the above program would be:

Enter number of elements: 5
Memory successfully allocated using malloc.
The elements of the array are: 1, 2, 3, 4, 5,

3. void *realloc(void *p, size_t size)

The function realloc changes the size of the object pointed by p to size. The contents will be unchanged upto minimum of the old and new sizes. If the new size is larger, the new space is uninitialized. realloc returns a pointer to the new space, or NULL if the request connot be satisfied, in which case ***p **is unchanged.
Please refer to the below code to understand its implementation:

#include <stdio.h> 
#include <stdlib.h>   
int main() 
{ 
    int* ptr; 
    int n, i; 
    n = 5; 
    printf("Enter number of elements: %d\n", n);
    ptr = (int*)calloc(n, sizeof(int)); 
    if (ptr == NULL) { 
        printf("Memory not allocated.\n"); 
        exit(0); 
    } 
    else {
        printf("Memory successfully allocated using calloc.\n");
        for (i = 0; i < n; ++i) { 
            ptr[i] = i + 1; 
        } 
        printf("The elements of the array are: "); 
        for (i = 0; i < n; ++i) { 
            printf("%d, ", ptr[i]); 
        } 
        n = 10; 
        printf("\n\nEnter the new size of the array: %d\n", n); 
        ptr = realloc(ptr, n * sizeof(int)); 
        printf("Memory successfully re-allocated using realloc.\n"); 
        for (i = 5; i < n; ++i) { 
            ptr[i] = i + 1; 
        } 
        printf("The elements of the array are: "); 
        for (i = 0; i < n; ++i) { 
            printf("%d, ", ptr[i]); 
        } 
        free(ptr); 
    } 
    return 0; 
} 

The output for the above code is:

Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5, 

Enter the new size of the array: 10
Memory successfully re-allocated using realloc.
The elements of the array are: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,

4. void free(void *p)

The function free deallocates the space pointed by p. It does nothing if p is NULL. p must be a pointer to space previously allocated by calloc, malloc or realloc.
Please refer to the below code to understand its implementation:

#include <stdio.h> 
#include <stdlib.h>   
int main() 
{ 
    int *ptr;
    int n, i; 
    printf("Enter number of elements: %d\n", n); 
    ptr = (int*)malloc(n * sizeof(int));
    if (ptr == NULL) { 
        printf("Memory not allocated.\n"); 
        exit(0); //Explained below.
    } 
    else { 
        // Memory has been successfully allocated 
        printf("Memory successfully allocated using malloc.\n"); 
        // Free the memory 
        free(ptr); 
        printf("Malloc Memory successfully freed.\n");
    } 
    return 0; 
} 

The output of the following code is:

Enter number of elements: 5
Memory successfully allocated using malloc.
Malloc Memory successfully freed.

For Process Control:

1. void abort(void)

The function abort causes the program to terminate abnormally, as if by raise(SIGABRT).

#include <stdio.h>
#include <stdlib.h>
int main () {
   FILE *fp;
   printf("Going to open file1.txt\n");
   fp = fopen( "file1.txt","r" );
   if(fp == NULL) {
      printf("Going to abort the program\n");
      abort();
   }
   printf("Going to close nofile.txt\n");
   fclose(fp);
   return(0);
}

If the file file1.txt is not found, then the output would be:

Going to open file1.txt                                                    
Going to abort the program                                                  
Aborted (core dumped)

2. void exit(int status)

The function exit causes normal program termination. atexit functions are called in reverse order of registration, open files are flushed, open streams are closed, and control is returned to the environment. The way status is returned is implementation dependent, but 0 is taken as a successful termination.

#include <stdio.h>
#include <stdlib.h>
int main () {
   printf("Start of the program....\n");
   printf("Exiting the program....\n");
   exit(0);
   //The below code is not executed.
   printf("End of the program....\n");
   return(0);
}

The ouptput of the above code would be:

Start of the program....
Exiting the program....

3. int atexit( void (*fcn)(void))

This is a very popularly used function used when you want some function to be executed before the program exits.
atexit registers the function fcn to be called when the program terminates normally. It returns non-zero if the registration cannot be made.
Please refer to the below code for more information:

#include <stdio.h>
#include <stdlib.h>
void fcn () {
   printf("This is fcn...\n");
}
int main () {
   /* register the termination function */
   atexit(fcn);
   printf("Starting  main program...\n");
   printf("Exiting main program...\n");
   return(0);
}

The output of the following code would be:

Starting main program...
Exiting main program...
This is fcn...

4. int system(const char *s)

The function system passes the string s to the environment for execution. If s is NULL. system returns non-zero if there is a command processor. If s in not NULL, the return value is implementation-dependent.
**PS:**This is implementation dependent.
Consider the below code:

#include <stdio.h>
#include <string.h>

int main () {
   char command[50];
   strcpy( command, "dir" );
   system(command);
   return(0);
} 

The output I get when I execute this on my linux machine is :
Screenshot-from-2020-05-07-00-10-01-1
You can see that the command dir and executing the program do the same task. This is because the command "dir" is what is stored by the string command in the above code.

5. char *getenv(const char *name)

getenv returns the environment string associated with name, or NULL if no string exists. Details are implementation-dependent.
The below program shows use of the getenv function.

#include <stdio.h>
#include <stdlib.h>
int main () {
   printf("PATH : %s\n", getenv("PATH"));
   printf("HOME : %s\n", getenv("HOME"));
   printf("ROOT : %s\n", getenv("ROOT"));
   return(0);
}

The Output of the program on my machine (linux based) is:

PATH: home/vishnu/miniconda3/condabin:/home/vishnu/.nvm/versions/node/v11.0.0/bin:/home/vishnu/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
HOME : /home/vishnu
ROOT : (null)

Sorting And Searching Algorithms:

1. void *bsearch(const void *key, const void *base, size_t n, size_t size, int(*cmp)(const void *keyval, cont void *datum))

bsearch searches base[0]...[n-1] for an item that matches *key. The function cmp must return negative if its first argument (the search key) is less than its second, zero if equal, and positive if greater. Items in the array base must be in ascending order. bsearch returns a pointer to a matching item, or NULL if none exists.
The below program could aid your understanding:

#include <stdio.h>
#include <stdlib.h>
int cmpfunc(const void * a, const void * b) 
{
   return ( *(int*)a - *(int*)b );
}
int values[] = { 5, 20, 29, 32, 63 };
int main () 
{
   int *item;
   int key = 29;
   /* using bsearch() to find value 29 in the array */
   item = (int*) bsearch (&key, values, 5, sizeof (int), cmpfunc);
   if( item != NULL ) {
      printf("Found item = %d\n", *item);
   } else {
      printf("Item = %d could not be found\n", *item);
   }
   return(0);
}

The output of the following program is:

Found item = 29

2. void qsort(void *base, size_t n, size_t size, int (*cmp)(const void *, const void *))

qsort sorts into ascending order an array base[0]...base[n-1] of objects of size size. The comparision function cmp is as in bsearch.
The below code could aid your understanding:

#include <stdio.h>
#include <stdlib.h>
int values[] = { 88, 56, 100, 2, 25 };
int cmpfunc (const void * a, const void * b) {
   return ( *(int*)a - *(int*)b );
}
int main () {
   int n;
   printf("Before sorting the list is: \n");
   for( n = 0 ; n < 5; n++ ) {
      printf("%d ", values[n]);
   }
   qsort(values, 5, sizeof(int), cmpfunc);
   printf("\nAfter sorting the list is: \n");
   for( n = 0 ; n < 5; n++ ) {   
      printf("%d ", values[n]);
   }
   return(0);

The output of the above code is:

Before sorting the list is: 
88 56 100 2 25 
After sorting the list is: 
2 25 56 88 100

Mathematics:

1. int abs(int n)

abs returns the absolute value of its int argument.
Below is an example code:

#include <stdio.h>
#include <stdlib.h>
int main () {
   int a, b;
   a = abs(50);
   printf("value of a = %d\n", a);
   b = abs(-1);
   printf("value of b = %d\n", b);
   return(0);
}

The output of the code is :

value of a = 50
value of b = 1

2. long labs(long n)

labs returns the absolute value of its long argument.
Below is a sample code:

#include <stdio.h>
#include <stdlib.h>
int main () {
   long int a,b;
   a = labs(65987L);
   printf("Value of a = %ld\n", a);
   b = labs(-1005090L);
   printf("Value of b = %ld\n", b);
   return(0);
}

The output of the above code is:

Value of a = 65987
Value of b = 1005090

3. div_t div(int num, int denom)

div computes the quotient and the remainder of num/denom. The results are stored int the int members quot and rem of a structure of type div_t.
The below code shows a clear example:

#include <stdio.h>
#include <stdlib.h>
int main () {
   div_t output;
   output = div(27, 4);
   printf("Quotient part of (27/ 4) = %d\n", output.quot);
   printf("Remainder part of (27/4) = %d\n", output.rem);
   output = div(27, 3);
   printf("Quotient part of (27/ 3) = %d\n", output.quot);
   printf("Remainder part of (27/3) = %d\n", output.rem);
   return(0);
}

The output to the above code is :

Quotient part of (27/ 4) = 6
Remainder part of (27/4) = 3
Quotient part of (27/ 3) = 9
Remainder part of (27/3) = 0

4. ldiv_t ldiv(long num, long denom)

div computes the quotient and remainder of num/denom. the results are stored in the long members quot and rem of a structure of type ldiv_t.
An example for this is shown below:

#include <stdio.h>
#include <stdlib.h>
int main () {
   ldiv_t output;
   output = ldiv(100000L, 30000L);
   printf("Quotient = %ld\n", output.quot);
   printf("Remainder = %ld\n", output.rem);
   return(0);
}

The output for the above would be:

Quotient = 3
Remainder = 10000

The Data Types Included:

1. size_t

This is the unsigned integer type and is the result of the sizeof keyword. We have already seen this up in our functions.

2. wchar_t

This is an integer type of the size of a wide character constant.

3. div_t

This is the structure that is returned by the div function.

4. ldiv_t

This is the structure that is returned by the ldiv function.

The Macros Included:

1. NULL

This macro is the value of a null pointer constant.

2. EXIT_FAILURE

This is the value the exit function returns in case of failure.

3. EXIT_SUCCESS

This is the value the exit function returns in case of success.

4. RAND_MAX

This macro is the maximum value that is returned by the rand function.

5. MB_CUR_MAX

This macro is the maximum number of bytes in a multi-byte character set which cannot be larger than MB_LEN_MAX.

Question:

Which among the following functions has a return data type of unsigned long int?

strtoul
strtol
strtod
atol
Among these, only strtoul is the function which returns an unsigned long int.

With this article at OpenGenus, you must have the complete idea of using stdlib.h in C. Enjoy.