A better question might be: "Is it normal that pointers can't solve a problem?"
Smart pointers are a tool to make managing an object's memory use easier than using a non-smart pointer. Can a non-smart pointer solve every problem? No, but it can create more problems if the memory isn't managed properly.
Not every regular pointer uses heap memory via new/delete, all smart pointers do use heap/free store memory.
In the Before Times, before C++, C used pointers to pass objects into functions and access heap memory using manual memory management. When and where the memory was released was a major problem.
C++ introduced std::auto_ptr, the first C++ smart pointer.
https://en.cppreference.com/w/cpp/memory/auto_ptr
One problem is the workings of an auto_ptr was "wonky," copying one transferred the ownership to the destination, with some weird results. So the current crop of smart pointers was created. And std::auto_ptr was deprecated, then later removed from the C++ toolbox.
C++ also introduced "references," aliases to the object. Less overhead and no manual memory management at all. A reference is just a different name for the object.
Swapping two numbers using pointers:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
#include <iostream>
void Swap(int*, int*);
int main()
{
int a { 5 };
int b { 125 };
std::cout << "Before swap(*, *), a: " << a << ", b: " << b << '\n';
Swap(&a, &b); // <-- address-of operators
std::cout << "After swap(*, *), a: " << a << ", b: " << b << '\n';
}
void Swap(int* a, int* b)
{
int temp { *a };
*a = *b;
*b = temp;
}
|
Before swap(*, *), a: 5, b: 125
After swap(*, *), a: 125, b: 5 |
Using references:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
#include <iostream>
void Swap(int&, int&);
int main()
{
int a { 5 };
int b { 125 };
std::cout << "Before swap(&, &), a: " << a << ", b: " << b << '\n';
Swap(a, b);
std::cout << "After swap(&, &), a: " << a << ", b: " << b << '\n';
}
void Swap(int& a, int& b)
{
int temp { a };
a = b;
b = temp;
}
|
Before swap(&, &), a: 5, b: 125
After swap(&, &), a: 125, b: 5 |
References are generally preferred over pointers, even smart pointers. Pointers and References, while they are important tools every programmer needs to know and understand, are not the "one size fits all solution" for every problem.
Smart pointers relieve the programmer from the burden of manually managing memory use, though they can introduce problems of their own. They are a trade-off that is best assessed on an individual basis.
Choose the right tool for the right job at hand. Not every programming problem is a nail.