Memory Management in C++: New & Delete Operators
Memory Management in C++: New & Delete Operators
As we know that arrays store the homogeneous data, so most of the time, memory is allocated to
the array at the declaration time. Sometimes the situation arises when the exact memory is not
determined until runtime. To avoid such a situation, we declare an array with a maximum size,
but some memory will be unused. To avoid the wastage of memory, we use the new operator to
allocate the memory dynamically at the run time.
In C language, we use the malloc() or calloc() functions to allocate the memory dynamically at
run time, and free() function is used to deallocate the dynamically allocated memory. C++ also
supports these functions, but C++ also defines unary operators such as new and delete to
perform the same tasks, i.e., allocating and freeing the memory.
New operator
A new operator is used to create the object while a delete operator is used to delete the object.
When the object is created by using the new operator, then the object will exist until we
explicitly use the delete operator to delete the object. Therefore, we can say that the lifetime of
the object is not related to the block structure of the program.
Syntax
The above syntax is used to create the object using the new operator. In the above
syntax, 'pointer_variable' is the name of the pointer variable, 'new' is the operator, and 'data-
type' defines the type of the data.
Example 1:
int *p;
p = new int;
In the above example, 'p' is a pointer of type int.
Example 2:
float *q;
q = new float;
In the above example, 'q' is a pointer of type float.
In the above case, the declaration of pointers and their assignments are done separately. We can
also combine these two statements as follows:
int *p = new int;
float *q = new float;
If we do not use the free() function at the correct place, then it can lead to the cause of the
dangling pointer. Let's understand this scenario through an example.
#include <iostream>
#include<stdlib.h>
using namespace std;
int *func()
{
int *p;
p=(int*) malloc(sizeof(int));
free(p);
return p;
}
int main()
{
int *ptr;
ptr=func();
free(ptr);
return 0;
}
In the above code, we are calling the func() function. The func() function returns the integer
pointer. Inside the func() function, we have declared a *p pointer, and the memory is allocated to
this pointer variable using malloc() function. In this case, we are returning the pointer whose
memory is already released. The ptr is a dangling pointer as it is pointing to the released memory
location. Or we can say ptr is referring to that memory which is not pointed by the pointer.
Till now, we get to know about the new operator and the malloc() function. Now, we will see the
differences between the new operator and the malloc() function.
Differences between the malloc() and new
The new operator constructs an object, i.e., it calls the constructor to initialize an object
while malloc() function does not call the constructor. The new operator invokes the constructor,
and the delete operator invokes the destructor to destroy the object. This is the biggest difference
between the malloc() and new.
The new is an operator, while malloc() is a predefined function in the stdlib header file.
The operator new can be overloaded while the malloc() function cannot be overloaded.
If the sufficient memory is not available in a heap, then the new operator will throw an exception
while the malloc() function returns a NULL pointer.
In the new operator, we need to specify the number of objects to be allocated while in malloc()
function, we need to specify the number of bytes to be allocated.
In the case of a new operator, we have to use the delete operator to deallocate the memory. But
in the case of malloc() function, we have to use the free() function to deallocate the memory.
Syntax of new operator
type reference_variable = new type name;
where,
type: It defines the data type of the reference variable.
reference_variable: It is the name of the pointer variable.
new: It is an operator used for allocating the memory.
type name: It can be any basic data type.
For example,
int *p;
p = new int;
In the above statements, we are declaring an integer pointer variable. The statement p = new
int; allocates the memory space for an integer variable.
Syntax of malloc() is given below:
int *ptr = (data_type*) malloc(sizeof(data_type));
ptr: It is a pointer variable.
data_type: It can be any basic data type.
For example,
int *p;
p = (int *) malloc(sizeof(int))
The above statement will allocate the memory for an integer variable in a heap, and then stores
the address of the reserved memory in 'p' variable.
On the other hand, the memory allocated using malloc() function can be deallocated using the
free() function.
Once the memory is allocated using the new operator, then it cannot be resized. On the other
hand, the memory is allocated using malloc() function; then, it can be reallocated using realloc()
function.
The execution time of new is less than the malloc() function as new is a construct, and malloc is
a function.
The new operator does not return the separate pointer variable; it returns the address of the newly
created object. On the other hand, the malloc() function returns the void pointer which can be
further typecast in a specified type.
free vs delete in C++
In this topic, we are going to learn about the free() function and delete operator in C++.
free() function
The free() function is used in C++ to de-allocate the memory dynamically. It is basically a
library function used in C++, and it is defined in stdlib.h header file. This library function is
used when the pointers either pointing to the memory allocated using malloc() function or Null
pointer.
Syntax of free() function
Suppose we have declared a pointer 'ptr', and now, we want to de-allocate its memory:
free(ptr);
The above syntax would de-allocate the memory of the pointer variable 'ptr'.
free() parameters
In the above syntax, ptr is a parameter inside the free() function. The ptr is a pointer pointing to
the memory block allocated using malloc(), calloc() or realloc function. This pointer can also be
null or a pointer allocated using malloc but not pointing to any other memory block.
If the pointer is null, then the free() function will not do anything.
If the pointer is allocated using malloc, calloc, or realloc, but not pointing to any memory block
then this function will cause undefined behavior.
free() Return Value
The free() function does not return any value. Its main function is to free the memory.
Let's understand through an example.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int *ptr;
ptr = (int*) malloc(5*sizeof(int));
cout << "Enter 5 integer" << endl;
The above code shows how free() function works with malloc(). First, we declare integer pointer
*ptr, and then we allocate the memory to this pointer variable by using malloc() function. Now,
ptr is pointing to the uninitialized memory block of 5 integers. After allocating the memory, we
use the free() function to destroy this allocated memory. When we try to print the value, which is
pointed by the ptr, we get a garbage value, which means that memory is de-allocated.
Output
In the above example, we can observe that free() function works with a calloc(). We use the
calloc() function to allocate the memory block to the float pointer ptr. We have assigned a
memory block to the ptr that can have a single float type value.
Output:
The above code shows how free() function works with a NULL pointer. We have declared two
pointers, i.e., ptr1 and ptr2. We assign a NULL value to the pointer ptr1 and the address of x
variable to pointer ptr2. When we apply the free(ptr1) function to the ptr1, then the memory
block assigned to the ptr is successfully freed. The statement free(ptr2) shows a runtime error as
the memory block assigned to the ptr2 is not allocated using malloc or calloc function.
Output
Delete operator
It is an operator used in C++ programming language, and it is used to de-allocate the memory
dynamically. This operator is mainly used either for those pointers which are allocated using a
new operator or NULL pointer.
Syntax
delete pointer_name
For example, if we allocate the memory to the pointer using the new operator, and now we want
to delete it. To delete the pointer, we use the following statement:
delete p;
To delete the array, we use the statement as given below:
delete [] p;
Some important points related to delete operator are:
It is either used to delete the array or non-array objects which are allocated by using the new
keyword.
To delete the array or non-array object, we use delete[] and delete operator, respectively.
The new keyword allocated the memory in a heap; therefore, we can say that the delete operator
always de-allocates the memory from the heap
It does not destroy the pointer, but the value or the memory block, which is pointed by the
pointer is destroyed.
Let's look at the simple example of a delete operator.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int *ptr;
ptr=new int;
*ptr=68;
std::cout << "The value of p is : " <<*ptr<< std::endl;
delete ptr;
std::cout <<"The value after delete is : " <<*ptr<< std::endl;
return 0;
}
In the above code, we use the new operator to allocate the memory, so we use the delete ptr
operator to destroy the memory block, which is pointed by the pointer ptr.
Output
Types of Polymorphism
1. Compile-Time Polymorphism
This type of polymorphism is achieved by function overloading or operator overloading.
A. Function Overloading
When there are multiple functions with the same name but different parameters, then the
functions are said to be overloaded, hence this is known as Function Overloading. Functions
can be overloaded by changing the number of arguments or/and changing the type of
arguments. In simple terms, it is a feature of object-oriented programming providing many
functions that have the same name but distinct parameters when numerous tasks are listed
under one function name. There are certain Rules of Function Overloading that should be
followed while overloading a function.
Below is the C++ program to show function overloading or compile-time polymorphism:
// Driver code
int main()
{
Geeks obj1;
Output
value of x is 7
value of x is 9.132
value of x and y is 85, 64
Explanation: In the above example, a single function named function func() acts differently
in three different situations, which is a property of polymorphism. To know more about this,
you can refer to the article – Function Overloading in C++ .
B. Operator Overloading
C++ has the ability to provide the operators with a special meaning for a data type, this ability
is known as operator overloading. For example, we can make use of the addition operator (+)
for string class to concatenate two strings. We know that the task of this operator is to add two
operands. So a single operator ‘+’, when placed between integer operands, adds them and
when placed between string operands, concatenates them.
Below is the C++ program to demonstrate operator overloading:
class Complex {
private:
int real, imag;
public:
Complex(int r = 0, int i = 0)
{
real = r;
imag = i;
}
// Driver code
int main()
{
Complex c1(10, 5), c2(2, 4);
Output
12 + i9
Explanation: In the above example, the operator ‘+’ is overloaded. Usually, this operator is
used to add two numbers (integers or floating point numbers), but here the operator is made to
perform the addition of two imaginary or complex numbers. To know more about this one,
refer to the article – Operator Overloading .
2. Runtime Polymorphism
This type of polymorphism is achieved by Function Overriding. Late binding and dynamic
polymorphism are other names for runtime polymorphism. The function call is resolved at
runtime in runtime polymorphism . In contrast, with compile time polymorphism, the compiler
determines which function call to bind to the object after deducing it at runtime.
A. Function Overriding
Function Overriding occurs when a derived class has a definition for one of the member
functions of the base class. That base function is said to be overridden.
Function overriding Explanation
// Driver code
int main(void)
{
Animal d = Dog(); // accessing the field by reference
// variable which refers to derived
cout << [Link];
}
Output
Black
We can see that the parent class reference will always refer to the data member of the parent
class.
B. Virtual Function
A virtual function is a member function that is declared in the base class using the keyword
virtual and is re-defined (Overridden) in the derived class.
Some Key Points About Virtual Functions:
Virtual functions are Dynamic in nature.
They are defined by inserting the keyword “virtual” inside a base class and are always
declared with a base class and overridden in a child class
A virtual function is called during Runtime
Below is the C++ program to demonstrate virtual function:
// C++ Program to demonstrate
// the Virtual Function
#include <iostream>
using namespace std;
public:
// virtual function
virtual void display()
{
cout << "Called virtual Base Class function"
<< "\n\n";
}
void print()
{
cout << "Called GFG_Base print function"
<< "\n\n";
}
};
public:
void display()
{
cout << "Called GFG_Child Display Function"
<< "\n\n";
}
void print()
{
cout << "Called GFG_Child print Function"
<< "\n\n";
}
};
// Driver code
int main()
{
// Create a reference of class GFG_Base
GFG_Base* base;
GFG_Child child;
base = &child;
Output
Called virtual Base Class function
class base {
public:
virtual void print()
{
cout << "print base class" << endl;
}
// Driver code
int main()
{
base* bptr;
derived d;
bptr = &d;
return 0;
}
Output
print derived class
show base class
access_modifier:
// overridden function
return_type name_of_the_function(){}
};
access_modifier:
// overriding function
return_type name_of_the_function(){}
};
}
Example:
#include <iostream>
using namespace std;
class Parent {
public:
void GeeksforGeeks_Print()
{
cout << "Base Function" << endl;
}
};
int main()
{
Child Child_Derived;
Child_Derived.GeeksforGeeks_Print();
return 0;
}
Output
Derived Function
Variations in Function Overriding
1. Call Overridden Function From Derived Class
#include <iostream>
using namespace std;
class Parent {
public:
void GeeksforGeeks_Print()
{
cout << "Base Function" << endl;
}
};
int main()
{
Child Child_Derived;
Child_Derived.GeeksforGeeks_Print();
return 0;
}
Output
Derived Function
Base Function
The output of Call Overridden Function From Derived Class
2. Call Overridden Function Using Pointer
class Parent {
public:
void GeeksforGeeks()
{
cout << "Base Function" << endl;
}
};
int main()
{
Child Child_Derived;
return 0;
}
Output
Base Function
3. Access of Overridden Function to the Base Class
#include <iostream>
using namespace std;
class Parent {
public:
void GeeksforGeeks()
{
cout << "Base Function" << endl;
}
};
int main()
{
Child Child_Derived;
Child_Derived.GeeksforGeeks();
Output
Derived Function
Base Function
{
public:
// defining the overridden function
void GeeksforGeeks_Print()
{
cout << "I am the Parent class function" << endl;
}
};
{
public:
// defining of the overriding function
void GeeksforGeeks_Print()
{
cout << "I am the Child class function" << endl;
}
};
int main()
{
// create instances of the derived class
Child GFG1, GFG2;
Output
I am the Child class function
I am the Parent class function
Function Overloading Vs Function Overriding
Function Overloading Function Overriding
C++ Files
In C++ programming we are using the iostream standard library, it
provides cin and cout methods for reading from input and writing to output respectively.
To read and write from a file we are using the standard C++ library called fstream. Let us see
the data types define in fstream library is:
fstream It is used to create files, write information to files, and read information from files.
Let's see the simple example of writing to a text file [Link] using C++ FileStream
programming.
1. #include <iostream>
2. #include <fstream>
3. using namespace std;
4. int main () {
5. ofstream filestream("[Link]");
6. if (filestream.is_open())
7. {
8. filestream << "Welcome to javaTpoint.\n";
9. filestream << "C++ Tutorial.\n";
10. [Link]();
11. }
12. else cout <<"File opening is fail.";
13. return 0;
14. }
Output:
Let's see the simple example of reading from a text file [Link] using C++ FileStream
programming.
1. #include <iostream>
2. #include <fstream>
3. using namespace std;
4. int main () {
5. string srg;
6. ifstream filestream("[Link]");
7. if (filestream.is_open())
8. {
9. while ( getline (filestream,srg) )
10. {
11. cout << srg <<endl;
12. }
13. [Link]();
14. }
15. else {
16. cout << "File opening is fail."<<endl;
17. }
18. return 0;
19. }
Note: Before running the code a text file named as "[Link]" is need to be created and the
content of a text file is given below:
Welcome to javaTpoint.
C++ Tutorial.
Output:
Welcome to javaTpoint.
C++ Tutorial.
Let's see the simple example of writing the data to a text file [Link] and then reading the data
from the file using C++ FileStream programming.
1. #include <fstream>
2. #include <iostream>
3. using namespace std;
4. int main () {
5. char input[75];
6. ofstream os;
7. [Link]("[Link]");
8. cout <<"Writing to a text file:" << endl;
9. cout << "Please Enter your name: ";
10. [Link](input, 100);
11. os << input << endl;
12. cout << "Please Enter your age: ";
13. cin >> input;
14. [Link]();
15. os << input << endl;
16. [Link]();
17. ifstream is;
18. string line;
19. [Link]("[Link]");
20. cout << "Reading from a text file:" << endl;
21. while (getline (is,line))
22. {
23. cout << line << endl;
24. }
25. [Link]();
26. return 0;
27. }
Output:
The cin is an object which is used to take input from the user but does not allow to take the input
in multiple lines. To accept the multiple lines, we use the getline() function. It is a pre-defined
function defined in a <string.h> header file used to accept a line or a string from the input
stream until the delimiting character is encountered.
Where,
is: It is an object of the istream class that defines from where to read the input stream.
Return value
This function returns the input stream object, which is passed as a parameter to the function.
The above syntax contains two parameters, i.e., is and str. This syntax is almost similar to the
above syntax; the only difference is that it does not have any delimiting character.
Where,
is: It is an object of the istream class that defines from where to read the input stream.
Return value
This function also returns the input stream, which is passed as a parameter to the function.
First, we will look at an example where we take the user input without using getline() function.
1. #include <iostream>
2. #include<string.h>
3. using namespace std;
4. int main()
5. {
6. string name; // variable declaration
7. std::cout << "Enter your name :" << std::endl;
8. cin>>name;
9. cout<<"\nHello "<<name;
10. return 0;
11. }
In the above code, we take the user input by using the statement cin>>name, i.e., we have not
used the getline() function.
Output
In the above output, we gave the name 'John Miller' as user input, but only 'John' was displayed.
Therefore, we conclude that cin does not consider the character when the space character is
encountered.
1. #include <iostream>
2. #include<string.h>
3. using namespace std;
4. int main()
5. {
6. string name; // variable declaration.
7. std::cout << "Enter your name :" << std::endl;
8. getline(cin,name); // implementing a getline() function
9. cout<<"\nHello "<<name;
10. return 0;}
In the above code, we have used the getline() function to accept the character even when the
space character is encountered.
Output
In the above output, we can observe that both the words, i.e., John and Miller, are displayed,
which means that the getline() function considers the character after the space character also.
When we do not want to read the character after space then we use the following code:
1. #include <iostream>
2. #include<string.h>
3. using namespace std;
4. int main()
5. {
6. string profile; // variable declaration
7. std::cout << "Enter your profile :" << std::endl;
8. getline(cin,profile,' '); // implementing getline() function with a delimiting character.
9. cout<<"\nProfile is :"<<profile;
10. }
In the above code, we take the user input by using getline() function, but this time we also add
the delimiting character('') in a third parameter. Here, delimiting character is a space character,
means the character that appears after space will not be considered.
Output
We can also define the getline() function for character array, but its syntax is different from the
previous one.
Syntax
In the above syntax, there are two parameters; one is char*, and the other is size.
Where,
char*: It is a character pointer that points to the array.
Size: It acts as a delimiter that defines the size of the array means input cannot cross this size.
1. #include <iostream>
2. #include<string.h>
3. using namespace std;
4. int main()
5. {
6. char fruits[50]; // array declaration
7. cout<< "Enter your favorite fruit: ";
8. [Link](fruits, 50); // implementing getline() function
9. std::cout << "\nYour favorite fruit is :"<<fruits << std::endl;
10. return 0;
11. }
Output
In C++, exception is an event or object which is thrown at runtime. All exceptions are derived
from std::exception class. It is a runtime error which can be handled. If we don't handle the
exception, it prints exception message and terminates the program.
Advantage
It maintains the normal flow of the application. In such case, rest of the code is executed even
after exception.
C++ Exception Classes
In C++ standard exceptions are defined in <exception> class that we can use inside our
programs. The arrangement of parent-child class hierarchy is shown below:
All the exception classes in C++ are derived from std::exception class. Let's see the list of C++
common exception classes.
Exception Description
o try
o catch, and
o throw
C++ try/catch
In C++ programming, exception handling is performed using try/catch statement. The C++ try
block is used to place the code that may occur exception. The catch block is used to handle the
exception.
1. #include <iostream>
2. using namespace std;
3. float division(int x, int y) {
4. return (x/y);
5. }
6. int main () {
7. int i = 50;
8. int j = 0;
9. float k = 0;
10. k = division(i, j);
11. cout << k << endl;
12. return 0;
13. }
Output:
1. #include <iostream>
2. using namespace std;
3. float division(int x, int y) {
4. if( y == 0 ) {
5. throw "Attempted to divide by zero!";
6. }
7. return (x/y);
8. }
9. int main () {
10. int i = 25;
11. int j = 0;
12. float k = 0;
13. try {
14. k = division(i, j);
15. cout << k << endl;
16. }catch (const char* e) {
17. cerr << e << endl;
18. }
19. return 0;
20. }
Output:
The new exception can be defined by overriding and inheriting exception class functionality.
Let's see the simple example of user-defined exception in which std::exception class is used to
define the exception.
1. #include <iostream>
2. #include <exception>
3. using namespace std;
4. class MyException : public exception{
5. public:
6. const char * what() const throw()
7. {
8. return "Attempted to divide by zero!\n";
9. }
10. };
11. int main()
12. {
13. try
14. {
15. int x, y;
16. cout << "Enter the two numbers : \n";
17. cin >> x >> y;
18. if (y == 0)
19. {
20. MyException z;
21. throw z;
22. }
23. else
24. {
25. cout << "x / y = " << x/y << endl;
26. }
27. }
28. catch(exception& e)
29. {
30. cout << [Link]();
31. }
32. }
Output:
Output:
Note: In above example what() is a public method provided by the exception class. It is used to
return the cause of an exception.
Strings in C++
C++ strings are sequences of characters stored in a char array. Strings are used to store words
and text. They are also used to store data, such as numbers and other types of information.
Strings in C++ can be defined either using the std::string class or the C-style character
arrays.
1. C Style Strings
These strings are stored as the plain old array of characters terminated by a null character ‘\
0’. They are the type of strings that C++ inherited from C language.
Syntax:
char str[] = "GeeksforGeeks";
Example:
C++
int main()
{
Output
GeeksforGeeks
2. std::string Class
These are the new types of strings that are introduced in C++ as std::string class defined
inside <string> header file. This provides many advantages over conventional C-style strings
such as dynamic size, member functions, etc.
Syntax:
std::string str("GeeksforGeeks");
Example:
C++
int main()
{
string str("GeeksforGeeks");
cout << str;
return 0;
}
Output
GeeksforGeeks
One more way we can make strings that have the same character repeating again and again.
Syntax:
std::string str(number,character);
Example:
C++
#include <iostream>
using namespace std;
int main()
{
string str(5, 'g');
cout << str;
return 0;
}
Output:
ggggg
int main()
{
string s = "GeeksforGeeks";
string str("GeeksforGeeks");
cout << "s = " << s << endl;
cout << "str = " << str << endl;
return 0;
}
Output
s = GeeksforGeeks
str = GeeksforGeeks
2. Using C-style strings
Using C-style string libraries functions such as strcpy(), strcmp(), and strcat() to define
strings. This method is more complex and not as widely used as the other two, but it can be
useful when dealing with legacy code or when you need performance.
char s[] = {'g', 'f', 'g', '\0'};
char s[4] = {'g', 'f', 'g', '\0'};
char s[4] = "gfg";
char s[] = "gfg";
Example:
C++
int main()
{
return 0;
}
Output
s1 = gfg
s2 = gfg
s3 = gfg
s4 = gfg
Another example of C-style string:
C++
#include <iostream>
using namespace std;
int main()
{
string S = "Geeeks for Geeks";
cout << "Your string is= ";
cout << S << endl;
return 0;
}
Output
Your string is= Geeeks for Geeks
How to Take String Input in C++
String input means accepting a string from a user. In C++. We have different types of taking
input from the user which depend on the string. The most common way is to take input
with cin keyword with the extraction operator (>>) in C++. Methods to take a string as input
are:
cin
getline
stringstream
1. Using Cin
The simplest way to take string input is to use the cin command along with the stream
extraction operator (>>).
Syntax:
cin>>s;
Example:
C++
int main() {
string s;
cout<<"Enter String"<<endl;
cin>>s;
Output
Enter String
String is:
Output:
Enter String
GeeksforGeeks
String is: GeeksforGeeks
2. Using getline
The getline() function in C++ is used to read a string from an input stream. It is declared in
the <string> header file.
Syntax:
getline(cin,s);
Example:
C++
int main()
{
string s;
cout << "Enter String" << endl;
getline(cin, s);
cout << "String is: " << s << endl;
return 0;
}
Output
Enter String
String is:
Output:
Enter String
GeeksforGeeks
String is: GeeksforGeeks
3. Using stringstream
The stringstream class in C++ is used to take multiple strings as input at once.
Syntax:
stringstream stringstream_object(string_name);
Example:
C++
// C++ Program to demonstrate use of stringstream object
#include <iostream>
#include <sstream>
#include<string>
int main()
{
Output
GeeksforGeeks
to
the
Moon
How to Pass Strings to Functions?
In the same way that we pass an array to a function, strings in C++ can be passed to functions
as character arrays. Here is an example program:
Example:
C++
void print_string(string s)
{
cout << "Passed String is: " << s << endl;
return;
}
int main()
{
string s = "GeeksforGeeks";
print_string(s);
return 0;
}
Output
Passed String is: GeeksforGeeks
Pointers and Strings
Pointers in C++ are symbolic representations of addresses. They enable programs to simulate
call-by-reference as well as to create and manipulate dynamic data structures. By using
pointers we can get the first character of the string, which is the starting address of the string.
As shown below, the given string can be accessed and printed through the pointers.
Example:
C++
int main()
{
string s = "Geeksforgeeks";
return 0;
}
Output
Geeksforgeeks
Difference between String and Character array in C++
The main difference between a string and a character array is that strings are immutable, while
character arrays are not.
String Character Array
Strings define objects that can be represented The null character terminates a character
as string streams. array of characters.
The threat of
No Array decay occurs in strings as strings are
array decay
represented as objects.
is present in the case of the character array
A string class provides numerous functions for Character arrays do not offer inbuilt
manipulating strings. functions to manipulate strings.
Know more about the difference between strings and character arrays in C++
C++ String Functions
C++ provides some inbuilt functions which are used for string manipulation, such as the
strcpy() and strcat() functions for copying and concatenating strings. Some of them are:
Function Description
This function is used to resize the length of the string up to the given number of
resize()
characters.
push_back() This function is used to push the passed character at the end of the string
pop_back() This function is used to pop the last character from the string
Function Description
clear() This function is used to remove all the elements of the string.
strncmp() This function compares at most the first num bytes of both passed strings.
This function is similar to strcpy() function, except that at most n bytes of src
strncpy()
are copied
strrchr() This function locates the last occurrence of a character in the string.
This function appends a copy of the source string to the end of the destination
strcat()
string
This function is used to search for a certain substring inside a string and returns
find()
the position of the first character of the substring.
This function is used to replace each element in the range [first, last) that is
replace()
equal to old value with new value.
This function is used to compare two strings and returns the result in the form of
compare()
an integer.
In C++ inbuilt string iterator functions provide the programmer with an easy way to modify
and traverse string elements. These functions are:
Functions Description
begin() This function returns an iterator pointing to the beginning of the string.
end() This function returns an iterator that points to the end of the string.
Functions Description
rbegin() This function returns a reverse iterator pointing to the end of the string.
rend() This function returns a reverse iterator pointing to the beginning of the string.
cbegin() This function returns a const_iterator pointing to the beginning of the string.
cend() This function returns a const_iterator pointing to the end of the string.
crbegin() This function returns a const_reverse_iterator pointing to the end of the string.
Example:
C++
int main()
{
// declaring an iterator
string::iterator itr;
string s = "GeeksforGeeks";
itr = [Link]();
cout << "Pointing to the start of the string: " << *itr<< endl;
itr = [Link]() - 1;
cout << "Pointing to the end of the string: " << *itr << endl;
rit = [Link]();
cout << "Pointing to the last character of the string: " << *rit << endl;
rit = [Link]() - 1;
cout << "Pointing to the first character of the string: " << *rit << endl;
return 0;
}
Output
Pointing to the start of the string: G
Pointing to the end of the string: s
Pointing to the last character of the string: s
Pointing to the first character of the string: G
String Capacity Functions
In C++, string capacity functions are used to manage string size and capacity. Primary
functions of capacity include:
Function Description
This function returns the capacity which is allocated to the string by the
capacity()
compiler
shrink_to_fit() This function decreases the capacity and makes it equal to the minimum.
Example:
C++
#include <iostream>
using namespace std;
int main()
{
string s = "GeeksforGeeks";
cout << "The string after using resize function is " << s << endl;
[Link](20);
cout << "The capacity of string before using shrink_to_fit function is "<< [Link]() << endl;
cout << "The capacity of string after using shrink_to_fit function is "<< [Link]() << endl;
return 0;
}
Output
The length of the string is 13
The capacity of string is 15
The string after using resize function is GeeksforGe
The capacity of string before using shrink_to_fit function is 30
The capacity of string...
In conclusion, this article explains how strings can be defied in C++ using character arrays
and string classes. The string class provides more advanced features, while the character array
provides basic features but is efficient and easy to use. In this article, we also discussed the
various methods to take input from the user.
Templates in C++
A template is a simple yet very powerful tool in C++. The simple idea is to pass the data type as
a parameter so that we don’t need to write the same code for different data types. For example, a
software company may need to sort() for different data types. Rather than writing and
maintaining multiple codes, we can write one sort() and pass the datatype as a parameter.
C++ adds two new keywords to support templates: ‘template’ and ‘type name’. The second
keyword can always be replaced by the keyword ‘class’.
How Do Templates Work?
Templates are expanded at compiler time. This is like macros. The difference is, that the
compiler does type-checking before template expansion. The idea is simple, source code contains
only function/class, but compiled code may contain multiple copies of the same function/class.
Function Templates
We write a generic function that can be used for different data types. Examples of function
templates are sort(), max(), min(), printArray().
To know more about the topic refer to Generics in C++.
Example:
C++
// One function works for all data types. This would work
// even for user defined types if operator '>' is overloaded
template <typename T> T myMax(T x, T y)
{
return (x > y) ? x : y;
}
int main()
{
// Call myMax for int
cout << myMax<int>(3, 7) << endl;
// call myMax for double
cout << myMax<double>(3.0, 7.0) << endl;
// call myMax for char
cout << myMax<char>('g', 'e') << endl;
return 0;
}
Output
7
7
g
// Driver Code
int main()
{
int a[5] = { 10, 50, 30, 40, 20 };
int n = sizeof(a) / sizeof(a[0]);
return 0;
}
Output
Sorted array : 10 20 30 40 50
Class Templates
Class templates like function templates, class templates are useful when a class defines
something that is independent of the data type. Can be useful for classes like LinkedList,
BinaryTree, Stack, Queue, Array, etc.
Example:
C++
public:
Array(T arr[], int s);
void print();
};
int main()
{
int arr[5] = { 1, 2, 3, 4, 5 };
Array<int> a(arr, 5);
[Link]();
return 0;
}
Output
12345
public:
A() { cout << "Constructor Called" << endl; }
};
int main()
{
A<char, char> a;
A<int, double> b;
return 0;
}
Output
Constructor Called
Constructor Called
int main()
{
// This will call A<char, char>
A<char> a;
return 0;
}
Output
Constructor Called
return m;
}
int main()
{
int arr1[] = { 10, 20, 15, 12 };
int n1 = sizeof(arr1) / sizeof(arr1[0]);
char arr2[] = { 1, 2, 3 };
int n2 = sizeof(arr2) / sizeof(arr2[0]);
// Second template parameter
// to arrMin must be a
// constant
cout << arrMin<int, 10000>(arr1, n1) << endl;
cout << arrMin<char, 256>(arr2, n2);
return 0;
}
Output
10
1
Here is an example of a C++ program to show different data types using a constructor and
template. We will perform a few actions
passing character value by creating an object in the main() function.
passing integer value by creating an object in the main() function.
passing float value by creating an object in the main() function.
Example:
C++
// Main Function
int main()
{
// clrscr();
// passing character value by creating an objects
info<char> p('x');
return 0;
}
Output
A = x size of data in bytes:1
A = 22 size of data in bytes:4
A = 2.25 size of data in bytes:4
In general, when we want to use the multiply() function for integers, we have to call it like this:
multiply<int> (25, 5);
If we want to create an instance of this class, we can use any of the following syntax:
student<int> stu1(23);
or
student stu2(24);
Note: It is important to note thet the template argument deduction for a classes is only available
since C++17, so if we
Example of Template Argument Deduction
The below example demonstrates how the STL vector class template deduces the data type
without being explicitly specified.
C++
int main()
{
// creating a vector<float> object without specifying
// type
vector v1{ 1.1, 2.0, 3.9, 4.909 };
cout << "Elements of v1 : ";
for (auto i : v1) {
cout << i << " ";
}
Output
Elements of v1 : 1.1 2 3.9 4.909
Elements of v2 : 1 2 3 4
Note: The above program will fail compilation in C++14 and below compiler since class
template arguments deduction was added in C++17.
Function Template Arguments Deduction
Function template argument deduction has been part of C++ since the C++98 standard. We can
skip declaring the type of arguments we want to pass to the function template and the compiler
will automatically deduce the type using the arguments we passed in the function call.
Example: In the following example, we demonstrate how functions in C++ automatically
deduce their type by themselves.
C++
// C++ program to illustrate the function template argument
// deduction
#include <iostream>
using namespace std;
// driver code
int main()
{
auto result = multiply(10, 20);
std::cout << "Multiplication OF 10 and 20: " << result
<< std::endl;
return 0;
}
Output
Multiplication OF 10 and 20: 200
Note: For the function templates which is having the same type for the arguments like
template<typename t> void function(t a1, t a2){}, we cannot pass arguments of different types.
The class template argument deduction was added in C++17 and has since been part of the
language. It allows us to create the class template instances without explicitly definition the types
just like function templates.
Example: In the following example, we demonstrate how the compiler automatically class
templates in C++.
public:
student();
// parameterized constructor
student(string n, t m)
{
student_name = n;
total_marks = m;
}
void getinfo()
{
cout << "STUDENT NAME: " << student_name << endl;
cout << "TOTAL MARKS: " << total_marks << endl;
cout << "Type ID: " << typeid(total_marks).name()
<< endl;
}
};
int main()
{
// student <int> is used to fulfill
// template requirements
student<int> s1("vipul", 100);
student<int> s2("yash", 100.0);
[Link]();
[Link]();
return 0;
}
Output
STUDENT NAME: vipul
TOTAL MARKS: 100
Type ID: i
STUDENT NAME: yash
TOTAL MARKS: 100
Type ID: d
Here, i means int, and d means double.