Risks of Using Raw Pointers in C++
In C++, raw pointers hold memory addresses and provide direct control over memory. However, improper use can lead to problems like memory leaks, crashes, and security issues.
A raw pointer is a basic pointer type that directly stores the address of a memory location.
Example:
int x = 10;
// ptr holds address of x
int* ptr = &x;
Common Risks of Using Raw Pointers:
Memory Leaks
Raw pointers need manual deallocation using delete or delete[]. Forgetting to do so causes memory leaks, where allocated memory is never freed.
#include <iostream>
using namespace std;
int main() {
// Allocate memory for an integer
int* p = new int(42);
// Use the pointer
cout << "Value: " << *p;
// Forgot to delete p â memory leak happens
// delete p; // This is missing
return 0;
}
Output
Value: 42
Over time, this leaks memory and can exhaust system resources, especially in long-running programs.
Dangling Pointers
A dangling pointer points to memory that has been deallocated or gone out of scope.
#include <iostream>
using namespace std;
int main() {
int* p = new int(99);
// Memory freed
delete p;
// p still points to the freed memory
cout << "Dangling value (undefined): " << *p;
return 0;
}
Output
Dangling value (undefined): 0
Using a dangling pointer may result in crashes, data corruption, or unpredictable behaviour.
Double Deletion
If you delete the same pointer twice, the programâs behaviour is undefined.
#include <iostream>
int main() {
int* p = new int(7);
// First delete â OK
delete p;
// Second delete â undefined behavior
delete p;
return 0;
}
Output
Abort signal from abort(3) (SIGABRT)
*** Error in `./Solution': double free or corruption (fasttop): 0x0000000006382c20 ***
timeout: the monitored command dumped core
/bin/bash: line 1: 31 Aborted
Wild Pointers
A wild pointer is a pointer that is not initialized but is used anyway.
#include <iostream>
using namespace std;
int main() {
// Uninitialized pointer (wild)
int* p;
// Dangerous: writing to an unknown address
*p = 10;
cout << "Written to wild pointer";
return 0;
}
Output
Written to wild pointer
Ownership Confusion / Aliasing Example
When multiple raw pointers point to the same dynamically allocated memory, it's unclear who is responsible for deleting it.
#include <iostream>
using namespace std;
int main() {
int* p1 = new int(100);
// Both point to same memory
int* p2 = p1;
// Memory freed
delete p1;
// p2 still points to freed memory â dangling
cout << "p2 value (undefined): "
<< *p2;
// If we delete p2, we attempt to free
// same memory again undefined behavior
delete p2;
return 0;
}
Output
Abort signal from abort(3) (SIGABRT)
*** Error in `./Solution': double free or corruption (fasttop): 0x0000000025d57c20 ***
timeout: the monitored command dumped core
/bin/bash: line 1: 32 Aborted
This makes memory management error-prone and invites bugs like double deletion or dangling pointers.
No Bounds Checking
Raw pointers do not provide array bounds checking when used for dynamic arrays.
#include <iostream>
using namespace std;
int main() {
int* arr = new int[3]{1, 2, 3};
// Correct access
cout << "arr[0]: " << arr[0] << endl;
// Undefined behavior â writing beyond
// array size
arr[5] = 42;
cout << "Out-of-bounds write done";
delete[] arr;
return 0;
}
Output
arr[0]: 1 Out-of-bounds write done
Overwriting adjacent memory may corrupt data or crash the program.