Hacker News new | past | comments | ask | show | jobs | submit login

I'm completely ignorant about C++, so I will ask this question: What's the state of memory management in modern C++? Is it easier to avoid shooting yourself in the foot? Can you write code that is completely safe?

I've always flat-out avoided C++ because I don't think I will be able to handle memory management for a large program; It'll be riddled with security holes and memory leaks.

Unfortunately, many OSS programs I want to contribute to are written in unmanaged languages like C or C++. As far as I'm aware, it's easier to get memory right in modern C++ compared to C, which hasn't received many updates.




Yes, it is possible, specially if you adopt modern idioms.

- Never use C style strings or arrays directly.

- Prefer STL data structures for memory management (unique_ptr , shared_ptr and others)

- Don't use C style enums (class enums are type safe)

- Don't use C casts

- When dealing with C libraries, always wrap them in safe C++ wrappers with safety invariants

- Always enable bounds checking for vectors, strings and iterators on debug builds.

- Always use references for pointer parameters that aren't supposed to be null

- Make effective use of RAII

Basically all boils down to don't program in C++ as if it was C with extras.


>Can you write code that is completely safe?

No. The modern C++ features like std::unique_ptr and std::shared_ptr replace old patterns of "malloc()/free()" and "new/delete". This ensures correct cleanup and avoids leaking memory.

However, there are other topics of "memory safety" such as preventing runtime behavior of buffer overruns and writing to invalid pointers. The virtual machines like Java JVM and C# CLR create a constrained memory area with extra runtime checks and the new C++ language features don't replicate that type of memory safety. Also, those "managed" languages don't expose raw pointers as a 1st class programming feature (e.g. don't use "unsafe" blocks) so that in itself creates an environment of extra memory safety.


"This ensures correct cleanup and avoids leaking memory."

Although shared_ptr does open you up to a whole new class of bugs, with circular references causing memory leaks and object lifetimes being harder to reason about, especially in a multi-threaded environment.

I agree in general, though, things are a lot better.


> I'm completely ignorant about C++, so I will ask this question: What's the state of memory management in modern C++? Is it easier to avoid shooting yourself in the foot? Can you write code that is completely safe?

I would not say completely safe if we only consider the language, but on the rare occurence of a memory bug, usage of asan / ubsan of GCC and Clang (both have different sets of checkers), -D_GLIBCXX_DEBUG and clang-tidy, it's frankly impossible to have this kind of bugs. Just running by default with -fsanitize=address -fsanitize=undefined will help you to trivially eliminate so many bugs it's not even funny.

However, you fight the language much less than in Rust in my experience, and if you don't do memory allocations directly but instead use <vector> and others it will be a breeze.


If binary libraries are part of the build I wouldn't say that "it's frankly impossible to have this kind of bugs".

Sanitizers still have some issues with them.


I am of the opinion that binary distribution should disappear. It's not a problem in 99% of the languages out there, why should it be one in C / C++ ?


Not everyone likes to give their code away for free, or has cluster based build environments.


>Can you write code that is completely safe?

Yes. Just don't use raw pointers. Use unique_ptr, shared_ptr and weak_ptr instead.


smart pointers are a good start, but completely safe is a pretty big exaggeration.

Just off the top of my head smart pointers do not protect against:

- null pointer dereferences

- out of bounds array access

- iterator invalidation

- dangling (non-owning) references



Also, keep things on the stack (C++11 onward has features that allow avoiding copies).


These things don't make it safe in the security sense. They just help against memory leaks.


I don't think you can ever write code that's completely safe then, if nothing else some processor flaw will come along and ruin everything.


While it's true that processor flaws destroy the assumptions that higher level components (such as any/all programming languages) build on, you don't need to go nearly that far to see unsafety in C++, even using only the most modern techniques: use-after-move of many types is undefined behaviour (for instance, dereferencing a std::unique_ptr that has been moved from), and iterator invalidation & dangling references aren't addressed by those smart pointers at all.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: