When programmers call code unsafe, what they mean is the code can be unpredictable, and unpredictability leads to unintentional behaviors, which are generally bad since good behaviors are intentional.
Code can be unpredictable because it's not written in a vacuum. Not only does code exist within the context of other code, it exists within the context of a compiler or interpreter, possibly a runtime, an operating system and firmware, a CPU architecture and memory and disk and networking and, of course, user input. All of these things make for an incredibly complex system, and incredibly complex systems produce emergent behaviors. So it is very difficult to work within such a system and add behaviors to it without creating unintended consequences. This is especially true the more complex the interactions of the components of the system, and c/c++ allow for very complex interactions.
There's more to it than that of course, but I think that's what underlies most of it.