Teaching data structures with C++: should I go with smart instead of raw pointers? I teach an intro to programming course which covers mostly the basics (data types, control flows, functions, arrays, pointers, singly linked lists, circular linked lists, doubly linked lists, without any OOP concepts). The course is taught using C++ but the focus is not on C++ but on the core concepts (the language is just there for implementation, so we only cover the very basics of it).

So far we've been using raw pointers to build linked lists. But I was wondering if students would benefit from switching to smart pointers. I know there are many pros to smart pointers, but I also fear students (who are novice to programming) would "get used" to leaving the cleanup to the compiler, as they wouldn't need to worry about dangling pointers or memory leak problems.

I think the benefits of raw pointers are that students acquire good practices (same reason they don't learn about high-level structures like vectors or maps yet, until they go on the next course and start with OOP). Also I think raw pointers could be a more "standard" way to learn linked lists, since the course doesn't focus on C++ but on the programming fundamentals, and the more C++ specific it gets, the harder it might be to transfer these concepts to a different language.

So for now I've always believed it a good idea to stick to raw pointers, but I don't want to trust my (limited) knowledge on the matter and would like to hear other opinions :)
In my view, C++ isn't a toy. It is a professional language that should be approached in a professional way. With that in mind, the latest versions are a vast improvement in safety over the earlier versions. 

Bjarne Stroustrup once said something like: In C you can shoot yourself in the foot. In C++ you can blow your leg off. 

That said, use C++:17 or later and use smart pointers. There is no reason to teach students techniques that are considered obsolete. Find a good book that is compatible with that philosophy, not one that uses a "historical" approach. The past was left behind for a reason. 

Alternatively, teach C if you want to teach lower level concepts or Java for higher ones. 

I'll note that many of us had to take an historical approach to C++ since we started when it was only a preprocessor for C itself. It has come a long way since then and modern developments have made it safer. 

An anecdote might be instructive. I once spent 24 hours finding an allocation bug in a C++ program. The correction required a single character change in the source. Not very productive. Smart pointers would have made such things much better. I now much prefer languages with good garbage collectors to having to solve the memory management problem again (and again) in every program.