I was working with a very large C++ codebase and saw some segmentation faults due to wrong usage of smart pointers. The errors are mostly due to usage of a memory location after deallocation. One simple example of this is as follows:
class Foo {
private:
// a raw pointer
int* p;
public:
Foo(int* q): p(q) {}
void Show() {
std::cout << *p << 'n';
}
};
Foo* GetFoo() {
std::unique_ptr<int> sp = std::make_unique<int>(5);
// passing the pointer but not moving it
return new Foo(sp.get());
}
Now the sp
pointer will get deallocated as GetFoo
goes out of scope and when we do this elsewhere, it will show segmentation fault:
Foo* foo = GetFoo();
foo->Show(); // undefined behavior due to heap-usage-after-free
These kind of errors are too frequent in large codebases and are mostly due to erroneous code compiled from different translation units. I have two questions around it:
-
Other than using shared pointers, is there any better way to ensure that the object underlying
sp
lives as long as theFoo
object is in scope? -
Is there a way to use static analysis to find such errors in code? Static analyzers like clang-tidy are not useful here as they do not work in cross-TU.