new
new is used in many programming languages such as Java, C++, and C# to allocate memory on the heap for a new object or array and to initialize it. When new is used, it creates an instance of a class or allocates an array, calling the appropriate constructor to initialize the object if it’s a class instance. The memory allocated using new remains allocated until explicitly deallocated by the programmer or managed by a garbage collector, depending on the language. In languages like C++, it is crucial to pair new with delete to avoid memory leaks. In Java and C#, garbage collection automates the management of memory cleanup, reducing the burden on developers to manually manage memory but still requiring careful handling to avoid excessive memory usage.
Functions of new:
-
Memory Allocation:
Allocates memory on the heap for a new object or array, ensuring that the program has the necessary space to store the data structures.
-
Constructor Invocation:
When creating an instance of a class, new automatically invokes the constructor of that class to initialize the object. This includes setting initial values and performing any setup required when an object is created.
-
Return Pointer or Reference:
In languages like C++ and C#, new returns a pointer or a reference to the newly allocated memory, allowing the program to access and manipulate the object or array.
-
Type Safety:
Ensures type safety by allocating memory for a specific type, thereby reducing errors like type mismatches that can occur in loosely typed or dynamically typed languages.
-
Encapsulation Support:
By using new to create objects, languages support the principles of encapsulation, allowing objects to manage their state and behavior internally and exposing only necessary aspects through methods.
-
Dynamic Memory Management:
Facilitates dynamic memory management, allowing programs to handle variable amounts of data that are not known at compile time.
-
Array Initialization:
When used with arrays, new not only allocates memory but can also initialize array elements to default values depending on the language and type, such as zeros for integral types or null for object references.
-
Facilitates Polymorphism:
By allocating objects of derived classes through base class pointers or references, new plays a crucial role in supporting runtime polymorphism, allowing the invocation of overridden methods through base class pointers or references.
Example of new:
This example will create a Person class and then use new to instantiate an object of that class.
// Define the Person class with attributes and a constructor
class Person {
String name;
int age;
// Constructor to initialize the Person object
Person(String name, int age) {
this.name = name;
this.age = age;
}
// Method to display information about the person
void displayInfo() {
System.out.println(“Name: ” + name + “, Age: ” + age);
}
}
// Main class to run the program
public class Example {
public static void main(String[] args) {
// Using ‘new’ to create a new Person object
Person person = new Person(“John Doe”, 30);
// Calling a method on the new object
person.displayInfo(); // Output: Name: John Doe, Age: 30
}
}
In this example:
- new keyword is used to create an instance of the Person
- Memory is allocated for the new Person object, and the constructor Person(String name, int age) is called with the arguments “John Doe” and 30.
- new keyword returns a reference to the newly created object, which is then stored in the variable person.
- displayInfo method is then called on the person object to display its attributes.
malloc( )
malloc() is a function in C used for dynamic memory allocation. It stands for “memory allocation” and is part of the C standard library, defined in <stdlib.h>. When called, malloc() allocates a block of memory of the specified size and returns a pointer to the beginning of the block. The size of the memory block is provided as an argument in bytes. If the memory allocation succeeds, it returns a void pointer (void*) to the allocated space. If the allocation fails, it returns a NULL pointer. The allocated memory is not initialized, meaning it contains indeterminate values. Users typically cast the return value to the appropriate pointer type for further use. It’s crucial to free the allocated memory using free() to prevent memory leaks.
Functions of malloc( ):
-
Dynamic Memory Allocation:
It allocates a specified amount of memory dynamically, during runtime, unlike static or automatic memory allocation.
-
Memory Allocation for Arrays:
It can be used to allocate memory for an array when the size of the array is not known at compile time but is determined during execution.
-
Memory Allocation for Structures:
Useful for allocating memory for structures when you need a new instance without knowing the number of instances needed during compile time.
-
Flexibility in Memory Management:
Provides the flexibility to control how much memory is allocated, which is particularly useful for data structures like linked lists, graphs, and trees where the size may change dynamically.
-
Handling Large Data:
Essential for handling large data that cannot be declared statically on the stack, particularly in applications like image processing and large matrix computations.
-
Modular Programming:
Facilitates modular programming by allowing memory allocation to be handled separately, which can simplify complex programming tasks and improve code reusability.
-
Optimization of Memory Usage:
Helps in optimizing memory usage by allocating only as much memory as needed during runtime.
-
Return Value Utilization:
Provides feedback about memory allocation success or failure through its return value (returns NULL if memory allocation fails), which can be used to implement error handling in programs.
Example of malloc( ):
Here’s an example of how the malloc() function is used in C to dynamically allocate memory for an array of integers and initialize it:
#include <stdio.h>
#include <stdlib.h> // Required for malloc and free
int main() {
int n, i;
int *ptr;
printf(“Enter the number of elements: “);
scanf(“%d”, &n);
// Dynamically allocate memory using malloc()
ptr = (int*) malloc(n * sizeof(int));
// Check if the memory has been successfully allocated by malloc or not
if (ptr == NULL) {
printf(“Memory not allocated.\n”);
exit(0);
}
else {
// Memory has been successfully allocated
printf(“Memory successfully allocated using malloc.\n”);
// Get the elements of the array
for (i = 0; i < n; ++i) {
ptr[i] = i + 1; // Assign elements in ptr
}
// Print the elements of the array
printf(“The elements of the array are: “);
for (i = 0; i < n; ++i) {
printf(“%d “, ptr[i]);
}
}
// Deallocate the memory
free(ptr);
return 0;
}
In this example:
- Memory for an array of integers is dynamically allocated based on user input for the number of elements (n).
- After allocation, the code checks if malloc() returned NULL (indicating failure to allocate memory), and if not, initializes and prints the array.
- Finally, free() is used to deallocate the memory, preventing memory leaks.
Key differences between new and malloc( )
Aspect |
new (C++) |
malloc() (C) |
Language | C++ | C |
Memory Initialization | Constructor calls | No initialization |
Type Safety | Type safe | Not type safe |
Return Type | Exact type | void* |
Error Handling | Throws exception | Returns NULL |
Memory Deallocation | delete | free |
Overloadability | Yes | No |
Handling Arrays | Supports constructors | Just allocates space |
Required Header | No specific | <stdlib.h> |
Casting | No casting required | Requires casting |
Allocation Failure | Bad allocation exception | Returns NULL |
Ease of Use | Higher level | More manual |
Size Calculation | Automatic | Manual size calculation |
Memory Alignment | Proper alignment | Proper alignment |
Usage in Code | Object-oriented | Procedural |
Key Similarities between new and malloc( )
- Purpose:
Both are used for dynamic memory allocation, allowing programs to allocate memory at runtime.
-
Heap Allocation:
They allocate memory from the heap, which is the area of memory used for dynamic memory allocation.
- Flexibility:
Both provide the flexibility to allocate memory as needed during runtime, which is useful for data whose size is not known at compile time and can grow dynamically.
-
Manual Management:
Memory allocated by both new and malloc() must be explicitly freed by the programmer to avoid memory leaks. In C++, delete is used to free memory allocated by new, while in C, free() is used for memory allocated by malloc().
-
Memory Overhead:
Each function incurs some overhead for managing the memory they allocate, as the system needs to maintain information about the allocated memory blocks.
-
Return of Memory Address:
Both functions ultimately provide the address of the allocated memory block, enabling the program to access and manipulate the allocated memory.