> should I worry about what I'm allocating to the heap and what I'm leaving up to the stack?
> I'm trying to adapt better practices and habits as I learn them and was curious about this one.
The basic rules for this are simple; learning good habits early is easy.
Unlearning bad programming habits after they have set in tends to be quite hard.
Adapted/extracted from CppCoreGuidelines
https://github.com/isocpp/CppCoreGuidelines
1.
Favour scoped objects.
A scoped object is a local object, a global object, or a member. ...
The members of a scoped object are themselves scoped and the scoped object's constructor and destructor manage the members' lifetimes.
1 2 3 4 5 6 7 8 9 10 11 12
|
void bad_function( int n )
{
auto p = new Gadget{n};
// ...
delete p;
}
void good_function( int n)
{
Gadget g{n};
// ...
}
|
2.
Avoid calling new and delete explicitly
The pointer returned by
new should belong to a resource handle (that can call
delete). If the pointer returned by
new is assigned to a plain/naked pointer, the object can be leaked.
In a large program, a naked
delete (that is a
delete in application code, rather than part of code devoted to resource management) is a likely bug.
3.
Use std::unique_ptr or std::shared_ptr to represent ownership.
A raw pointer - a
T* -
is non-owning.
They can prevent resource leaks.
4.
Favour the standard library over other libraries and "handcrafted code"
Code using a library can be much easier to write than code working directly with language features, much shorter, tend to be of a higher level of abstraction, and the library code is presumably already tested. The ISO C++ standard library is among the most widely known and well tested libraries. It is available as part of all C++ Implementations.
5.
Favour std::array or std::vector over C-style arrays
C arrays are less safe, and have no advantages over
std::array and std::vector.
For a fixed-length array, use
std::array, which does not degenerate to a pointer when passed to a function and does know its size.
For a variable-length array, use
std::vector, which additionally can change its size and handles memory allocation.
6.
Favour std::string over dynamically allocated C-style strings
C-style strings are less safe, and have no advantages over
std::string
7.
Immediately give the result of an explicit resource allocation to a manager object
If you don't, an exception or a return may lead to a leak.
1 2 3 4 5 6 7 8 9 10 11 12
|
void bad_function( std::string path )
{
auto file = std::fopen( path.c_str(), "r" );
// ...
std::fclose(file) ;
}
void good_function( std::string path )
{
std::ifstream file(path) ;
// ...
}
|