New Operator In C++ | Syntax, Working, Uses & More (+Examples)
The new operator in C++ programming plays a vital role in dynamic memory allocation and object construction. It enables programmers to allocate memory at runtime and create objects dynamically. Understanding the new operator is crucial for efficient memory management and building flexible applications. In this article, we will explore the usage, syntax, and important considerations when using the new operator in C++ programs.
What Is The New Operator In C++?
The new operator in C++ language is used to dynamically allocate memory from the heap at runtime. If there is sufficient memory, it allocates the required memory, returns the address of the allocated block, and initializes it (if needed).
We can access and manipulate this newly allocated memory using a pointer variable (that points to this location). The new operator is especially useful when working with arrays, classes, or other large data structures that need to be created during program execution. Let's look at the syntax of new operator, when used for single objects/ variables and when used for arrays.
Syntax Of The New Operator In C++
data_type *pointer_variable = new dataType; // For single variables
data_type *pointer_variable = new dataType[size]; // For arrays
Here,
- The term data_type refers to the type of data the pointer variable, and dataType refers to the type of data we will store in the variable/ location being pointed to. Ideally, both of these should be the same.
- The term pointer_variable refers to the name we give to the pointer variable that will store the address of the newly allocated memory. (The asterisk symbol (*) is the pointer notation.)
- In the second line of syntax, size refers to the number of elements the array will contain, and square brackets [] indicate the array notation.
Example- The snippet below showcases the implementation of the new operator/ new keyword in C++:
int *ptr = nullptr; // Pointer initialization expression with NULL
ptr = new int; // Then request memory for the variableOR
// Combine declaration of pointer and their assignment
int *ptr = new int;
The code above first allocates memory to a number or nullptr on the heap and stores the address of the memory in the pointer variable ptr. We can then use ptr to enter and replace numbers.
The use of a new operator to initialize value or create a memory block is demonstrated in the C++ program snippet below.
// Integer value initialized with value 21
int *p = new int(21);// Create an array of size 10.
int *x = new int[10];
Let's look at a full code example of the C++ new operator.
Code Example:
Output:
1 2 3 4 5
Explanation:
In the above code example-
- We include the <iostream> header file to use input/output operations. We also use the namespace std; statement to avoid writing std:: before every standard library element.
- Inside the main() function, we first dynamically allocate memory to an array using the new operator. Here:
- The new operator allocates memory for the an integer array type containing 5 values (integers), i.e., new int[5].
- In the same line, we assign this memory location to the integer pointer arr, i.e., int* arr. (It will point to the first element of the array)
- We then use a for loop to initialize the array elements with values from 1 to 5.
- Next, we use another for loop to print the values of the array elements.
- Finally, we deallocate the memory allocated for the array using the delete[] operator to avoid memory leaks.
Return Value Of New Operator In C++
The new operator in C++ returns a pointer to the heap memory, where dynamically allocated objects are stored.
- The type of the pointer returned depends on the type of the object being allocated. For example, if you're allocating an object of type int, the new operator will return a pointer of type int*.
- If the memory allocation fails, the new operator throws a std::bad_alloc exception by default. This behavior can be changed using the nothrow keyword, which causes the new operator to return a null pointer instead of throwing an exception.
Parameters Of New Operator In C++
- Count: This is an optional parameter that specifies the number of bytes to which memory will be allocated. The default value is 1.
- ptr: This parameter is used to specify the address of memory allocation where the new object should be placed.
- tag: This parameter (optional) is used to specify the allocation.
- alignment(al): This parameter (optional) is used to specify the alignment requirement to be used for allocating memory.
Check out this amazing course to become the best version of the C++ programmer you can be.
Example To Understand New Operator In C++
Let's understand the functionality of the new operator in C++ with the help of a code example.
Code Example:
Output:
Constructor called!
Doing something!
Destructor called!
Explanation:
- In this example, we define a simple class named MyClass with a constructor, descructor and member function:
- The constructor MyClass() is called automatically when a class object is created. It also prints "Constructor called!" to indicate that the object initialization has taken place.
-
- Then, we define destructor ~MyClass() called automatically for cleanup tasks, when an object is destroyed. It also prints "Destructor called!" to show when the object is being cleaned up.
- Next, we have a member function doSomething() which used std::cout to print a message- "Doing something!" to indicate some action is being performed by the object.
- Finally, the main() function return 0 to indicate that the program has been executed successfully.
The Grammar Elements Of The New Operator In C++
The new operator in C++ has the following grammar elements:
New Placement: This optional parameter specifies where the new object should be created in memory. This is an advanced feature primarily used in low-level memory management. For Example:
int arr[2] = { 1, 2 };
int* ptr = new (arr) int[2];
- type-id: It is a set of identifiers that allocates the object. It can be used in many contexts, such as notifications, dumps, etc. For Example:
int x = 5;
std::cout << typeid(x).name() << std::endl; // Output: i
- The new initializer: In this, the new operator allocates dynamic memory for the object and can be used to initialize the object at the same time. For Example:
int* p = new int(21); // initialize a single integer with value 21
- The noptr new declarator: This is a syntax used to create a new object or an array of objects with explicit constructor parameters. For Example:
int *ptr = new (std::nothrow) int[5]{1, 2, 3, 4, 5};
Storage Space Allocation
Allocated Storage refers to dynamic storage allocation or memory that is dynamically allocated at runtime using the new operator in C++. This memory is allocated on the heap, which is an area of memory reserved by a group allocating local variables.
When using the new operator to allocate memory, the compiler stores the requested memory size on the heap and returns a pointer to the first byte of the block. The size of the memory block depends on the size of the built-in data type being allocated, which can be determined at runtime.
Throwing Allocation
If memory cannot be allocated for the object, the new operator in C++ throws an exception, i.e., exception throw. This is called a "returning assignment" or a "review". By default, the new operator throws a std::bad_alloc exception if memory allocation fails. This exception can be caught using a try-catch block. Below is an example of the same.
Code Example:
Output:
Constructor called!
Memory allocation successful!
Destructor called!
Explanation:
In this code example-
- We define a class named MyClass with a constructor and a destructor, just like in the previous example.
- Inside the main() function, we use a try-catch block to handle potential memory allocation exceptions.
- In the try block, we attempt to allocate memory for a MyClass object using the new operator with the nothrow keyword.
- If the allocation succeeds, a valid pointer to the object is returned, and we print a message to the console. Finally, we delete the object to deallocate the memory using the delete operator.
- However, if the memory allocation fails due to insufficient memory, a std::bad_alloc exception is thrown.
- We catch this exception in the catch block and print an error message to the console, indicating that memory allocation failed followed by the exception's description using e.what().
The Nothrow Allocation
In this type of memory allocation, we use the nothrow expression of the new operator. It functions like regular dynamic memory allocation but with a key difference in error handling. If the allocation fails due to insufficient memory, it returns a nullptr instead of throwing a std::bad_alloc exception.
Code Example:
Output:
Constructor called!
Memory allocation successful!
Destructor called!
Explanation:
Just like in the previous two examples, we define a class MyClass with a constructor and destructor, but no member function.
- Inside the main() function, we we create obj, an object of MyClass and use the new operator with std::nothrow keyword to allocate memory to it.
- This keyword ensures that if the memory allocation fails, it does not throw an exception but instead returns a null pointer.
- Then, we use an if-else statement to check if the allocation was successful by using the inequality relational operator to see if obj is not null.
- If the condition is true, it means allocation successful, and the if-block is executed where the new operator returns a valid pointer to the object.
- As shown in the commented lines in the code, we can use this object as required and then release the allocated memory using delete obj.
- If the condition is false, it means allocation failed, then the control moves to the else block.
- The new operator in this case returns a null pointer (nullptr) and we print an error message to the console.
-
Finally, the program returns 0, indicating successful execution.
New Placement In C++
Placement new is different from the regular new operator in C++. It allows the programmer to specify a particular location in memory where an object should be constructed.
- Unlike the regular new, placement new does not allocate memory. Instead, it uses pre-allocated memory provided by the programmer.
- To use placement new, you need to provide a pointer to the pre-allocated memory where you want the object to be constructed. You also need to include the header <new> to use the placement new operator.
Code Example:
Output:
Constructor called! Value: 42
Value: 42
Value: 99
Destructor called! Value: 99
Explanation:
In this example,
- We define a MyClass class with a constructor, destructor, a setValue() method to modify the value, and a printValue() method to print the value.
- It also contains a private data member value (integer type), meaning it can only be accessed by components of the class.
- In the main() function, we first allocate raw memory for an object of MyClass using operator new.
- Next, we use placement new to construct an object of type MyClass at the specified memory location, passing the constructor argument 42.
- We then call printValue() to display the initial value, change the value to 99 using setValue(99), and print the updated value again using printValue().
- After using the object, we explicitly invoke the destructor with obj->~MyClass() to destroy the object and print the message to the console.
- Finally, we deallocate the raw memory using operator delete(memory).
How Does The C++ New Operator Works?
The new operator is used to allocate memory dynamically at runtime. When you use the new keyword in C++ to allocate memory, the following steps occur:
- The new operator first evaluates the type of the created object and decides how much memory to allocate.
- It then tries to allocate a linked memory of the desired size from the heap. If the memory allocation request is successful, a pointer to the first byte of the block is returned. If the allocation fails, a bad_alloc exception is thrown.
- If the allocation is successful, the new operator calls the object's constructor and initializes the memory block using the default constructor or the initializer constructor as specified in the new instructions.
- Finally, the new operator returns a pointer to the newly created object, which then can be used to access and modify objects stored in this memory.
When you allocate new memory, you need to deallocate it using the delete operator when it is no longer needed. Failure to do so can cause a memory leak where memory is allocated but not released, causing performance issues and potentially causing the program to run out of memory.
What Happens When Enough Memory In The Program Is Not Available?
When there is not enough memory available in a program to fulfill a memory allocation request, the undefined behavior will depend on the memory allocation function being used.
- New operator: If the new operator is used for an allocation (new type), an exception is thrown for std::bad_alloc when the memory allocation fails. You can catch this exception using a try-catch block to handle the error in your program.
- new(std::nothrow) operator: If you use the new(std::nothrow) operator to allocate memory and the allocation fails, it returns a nullptr instead of throwing an exception. You can check whether the allocation succeeded by verifying if the pointer is nullptr.
- Malloc Function: The malloc function in C returns a pointer (NULL) when memory allocation fails. It doesn't throw an exception. It is important to note that the direct use of the malloc() function is deprecated in C++. You should hence prefer to use a new operator instead.
Initializing Objects Allocated With New Operator In C++
Objects are allocated using the new operator and can be initialized using a variety of syntaxes. One way to instantiate an object is to use the constructor class. Below is an example of how to use the constructor to initialize an object with C++ new keyword.
Code Example:
Output:
42
Explanation:
In this example-
- We define a class named Box with a private data member m_value to store an integer value and public member functions Box(int value) and printValue().
- In the Box class, we define a constructor Box(int value) that takes an integer argument and initializes the private data member m_value with the provided value.
- We also define a member function printValue() that outputs the value of m_value using std::cout statement.
- In the main() function, we dynamically allocate memory for an object of the Box class using the new operator. This creates an instance of the class and calls the constructor with the value 42, which is stored in m_value. The pointer ptr holds the address of this newly created object.
- We then call the printValue() function using ptr->printValue(), which dereferences the pointer and prints the value 42 to the console.
- After printing the value, we deallocate the memory using delete ptr to free up the dynamically allocated memory and avoid memory leaks.
Lifetime Of Objects Allocated With The New Operator In C++
In C++, the lifetime of an object allocated using the new operator is determined by the programmer. This is in contrast to objects with automatic or static bytes of storage duration, which have their lifetime determined by the program structure.
When an object is dynamically allocated using new, it remains until explicitly declared using the delete operator. This means that the object can be extended beyond the point at which it was created, allowing it to be used by other parts of the program.
Code Example:
Output:
42
Explanation:
In this C++program-
- In the main() function, we dynamically allocate memory for an integer variable with the value of 42 using new operator.
- In the same line, we assign the address of the allocated valid memory location (where int is stored) to the pointer variable ptr.
- We then print the value to the console using std::cout command and the dereference operator (*) to access the integer value stored at the location ptr.
- Finally, we free the memory using the delete operator to avoid memory leaks.
Since objects are constantly allocated with new ones until they are released, it is important to ensure that all dynamically allocated objects are deallocated so that they can be removed when not needed.
What Is The Delete Operator In C++?
The delete operator is used to free up the dynamically allocated memory, that was previously allocated using the new operator in C++. When memory is allocated using new, it remains allocated until explicitly freed by the delete operator. Failing to deallocate memory will result in memory leaks, where the program consumes more and more memory over time without releasing it.
The Syntax For The Delete Operator
delete pointer_variable;
Here,
- pointer_variable is the name of the pointer that points to the newly allocated memory.
- The delete keyword marks the delete operator, which, when called, frees up the allocated memory. This memory can then be reused by the program or returned to the operating system.
Example:
int* ptr = new int;
*ptr = 21;
std::cout << "The value of the integer is: " << *ptr << std::endl;// Deallocate the memory when it is no longer needed
delete ptr;
The delete keyword here is used to deallocate memory that was allocated using the new operator in C++. If you forget to deallocate memory or use the wrong deallocation operator, you can end up with memory leaks or other problems.
Difference Between New And Delete Operator In C++
The new and delete operators are used for dynamic memory allocation and deallocation in C
++, respectively. Below are some key differences between the two operators:
Definition |
New operator |
Delete operator |
Usage |
The new operator is used to dynamically allocate memory for an object or array. |
The delete operator is used to free up the allocated memory. |
Syntax |
The new operator is followed by the user-defined data type of the object. |
The delete operator is followed by the memory address to be deallocated. |
Return type |
The new operator returns a pointer to the allocated memory. |
The delete keyword returns nothing. |
Size allocation |
The new operator is used to allocate a certain size of memory, which depends on the file type and the allocated object. |
The delete expression frees exactly the same memory allocated by the new. |
Handling of null pointers |
The new operator in throws an exception to std::bad_alloc if it fails to allocate the requested memory. |
The delete expression can be used safely with a null pointer without causing any errors. |
Looking for mentors? Find the perfect mentor for select experienced coding & software experts here.
Conclusion
The new operator in C++ is used to allocate memory at runtime. It allows you to create objects whose lifetime is independent of their declaration and allocate memory for arrays of objects whose size is unknown at the run time. The new operator in C++ returns a pointer to the new memory that can be used to access and modify objects stored in that memory.
It is important to properly manage the memory with the new, leaving the memory to the delete operator when it is not needed to avoid memory leaks. The new operator in C++ can also be used to instantiate an object in the constructor class and allocate sufficient memory using the operator new function without calling the constructor.
Frequently Asked Questions
Q. What is the delete operator in C++?
The delete operator is used to free up dynamically allocated memory that was previously allocated using the new operator. In other words, when you use the new operator to allocate memory to an object or a set of objects, you must free that memory when you are finished using it. This is where the delete operator comes into play.
For example:
int* ptr = new int;// Allocate memory for a single integer using new
delete ptr; // Free the memory using delete
Q. When to do dynamic memory allocation?
Dynamic memory allocation is a computer programming technique that allows programs to allocate and free memory at runtime. In other words, dynamic allocation is a way for programs to request for memory allocation from the operating system as needed rather than being limited to a fixed amount of memory at collection time. When allocating a multidimensional array, all dimensions except the first must be constant expressions that evaluate positive values.
Dynamic memory allocation is often used in programming languages such as C and C++, where the memory needs to be allocated and deallocated for the variables and for the data structures such as arrays, names, and trees. This is usually done using functions like malloc() and free() in C or the new and delete operators in C++.
Q. What is the new operator in C++?
The new operator is a keyword in the C++ programming language used to allocate memory for an object at runtime. It is often used to allocate memory for objects on the heap, which is a large pool of memory managed by a function.
The new operator is often used with a default constructor to initialize an allocated object. For example, if you want to allocate memory for an integer variable named "number", you can use the new operator as follows:
int* number = new int(20);
Q. Give an example of the new operator for a string in C++?
The block of code below showcases the use of C++ new keyword for string:
// Allocate a new string on the heap using the new operator
string* myString = new string("Hello, world!");// Free up the memory used by the string using the delete operator
delete myString;
In this example, we allocate a string object named myString on the heap using the new operator and call it Hello, world! We start with the value and then use the asterisk operator (*) to dereference the pointer and print the value of the string. Finally, we use the delete operator to free up the allocated memory used by the string.
Q. What is the difference between operator new and new operator?
- The operator new is a low-level function provided by the C++ standard library to allocate raw memory from the heap. It takes the size of the memory block to be allocated as its argument and returns a pointer to the beginning of the allocated block. Essentially, it just allocates memory but does not initialize it. The default operator new can be overridden by the user to provide custom memory allocation behavior.
- On the other hand, new operator, is a higher-level construct in the C++ language used to allocate memory for an object and invoke its constructor to initialize the object. The new operator internally calls operator new to allocate memory and then proceeds to construct the object in that allocated memory by calling the appropriate constructor.
Q. Can a new operator in C++ return null?
By default, the new operator in C++ does not return nullptr when memory allocation fails. Instead, it throws a std::bad_alloc exception. However, C++ provides a way to handle memory allocation failures more gracefully by using the not-throwing variant of new with std::nothrow. In this case, if memory allocation fails, the new operator will return nullptr rather than throwing an exception.
For Example:
int* ptr = new(std::nothrow) int; // Returns nullptr if allocation fails
if (!ptr) {
std::cout << "Memory allocation failed" << std::endl;
}
Here, new(std::nothrow) returns nullptr on failure.
You might also be interested in reading the following:
- Typedef In C++ | Syntax, Application & How To Use It (With Examples)
- Difference Between C And C++| Features | Application & More!
- 51 C++ Interview Questions For Freshers & Experienced (With Answers)
- Find In Strings C++ | Examples To Find Substrings, Character & More!
- Data Types In C++ | A Detailed Explanation With Examples