> My opinion is that there is no "right way" of doing C++, unlike, say, python.
There are, however, definitely wrong ways of doing things in C++. There's quite a few things in the STL that should have long since been deprecated if not outright removed.
Simple example is std::map. Absolutely horrible data structure. std::unordered_map is what you actually want, but to a beginner nothing really tells you that. You just think "I need a map, oh hey there's a std::map, perfect!" and go about your day completely unaware of how awful a data structure you just chose.
Another example that's a mistake made in C++ hello worlds of all things is std::endl. std::endl does not mean "end line", it means "\n + flush" (specifically '\n' - it does not do '\n\r' or '\r\n' conversions at all, the underlying file system does that). And flushing on every new line only makes sense for line-buffered things like std::out, but std::out already flushes on '\n' character. So std::endl in practice just leads to a ton of unnecessary & unexpected flushes.
> so you go with new, but if you don't want to deal with exceptions or just want a block of raw memory, you may want to go with malloc instead.
There's actually very little reason to ever use malloc. If you globally don't want exceptions just use -fno-exceptions. If you don't want exceptions in the small scope you're working in then use std::nothrow, eg: "new (std::nothrow) int[1024 * 1024]".
As for why you do this over malloc the reason is simple - it avoids overflow bugs. new int[size_t] never overflows. malloc(size_t * sizeof(int)) - well that overflows trivially, and that overflow results in security bugs.
Raw malloc would arguably be another case of "this is just wrong C++" rather than "this is a perfectly valid alternative". Raw free would belong in this case except for calloc, which is still very useful (and avoids the common overflow bug that malloc has). malloc's only saving grace is realloc, but now you're pretty deep into a specific edge case.