So, what's my point? It is, can smart pointers ala C++ be of any help here.
Very true. I like the way you put it, because it highlights that C++ is not the same language as C (exactly because it tries hard to avoid the shortcomings in C and has a very different set of abstractions).
I myself write a lot of systems-level code: utility tools, low-level libraries, service daemons, and such stuff.
There I use C, especially for libraries, as it is the lowest common denominator, and does not introduce any additional dependencies to other applications and libraries.
I do not use C++ there, because it introduces a runtime dependency to a particular version of the C++ standard library. (Right now on this machine, I only have 5.0.7 and 6.0.25 installed, so the likelihood of wanting to use something that depends on one while my C++ code uses the other, creating version conflicts, is low. But I've bitten by this before, when it was common a new version of the C++ runtime (dynamic libraries) appeared every couple of months on my machines.)
Note that in Linux, even pure-C++ dynamically linked binaries have a run time dependency on the standard C dynamic library. (Actually, *all* dynamically linked binaries on my system, even
rustc, are linked against the standard C dynamic library,
libc.so.6 in this case. Just checked via
ldd.)
I could use C++ for GUIs (and do for Qt on raw framebuffer), but I prefer to use Python3 + C for the low-level stuff instead; just a personal preference.
On the other end, for microcontrollers and embedded environments (including Arduino), I use a weird combination of freestanding C and a subset C++, with compiler extensions sprinkled on top. There, using a selected subset of C++ features, with a coding style/paradigm not really being "C" or "C++" but of this particular environments own, just works best for me.
So, choosing the toolset, including the programming language and associated libraries, is very, VERY important.
Even the set of libraries you use at the application level affects your approach. Consider Boost and Boehm GC for example. Or, if you do any math work in C, you've probably at some time met BLAS and LAPACK, which still carry their own flavour from their FORTRAN roots (only slightly hidden when shimmed by higher-level libraries like the Intel Math Kernel Library or AMD Optimizing CPU Libraries). Working with GNU Scientific Library (GSL) in C, and then having to go back to BLAS/LAPACK land, can be painful. For Fourier transforms, the concept of "wisdom" implemented by FFTW3 affects your applications down to run time and user help stuff. (There being many different ways to implement the computation of a particular transform, "wisdom" is the label used to denote that given a specific transform of a specific size a certain approach is computationally efficient, sometimes optimal. "Wisdom" is stored in per-user configuration files. Lack of "wisdom" makes your program slow, but gathering or generating "wisdom" is usually much much slower; but it only needs to be gathered once per dataset size and transform. A proper FFTW3-using program lets the user choose whether to do a particular operation in a wisdom-gathering manner, rely on existence of wisdom on the problem at hand, or to pick a balance in between so that even with complete lack of wisdom a reasonably efficient approach is used without spending any effort to optimize repeated similar transforms of the same size. See? Changes the entire "feel" of the program, just by choosing to use a particular library.)