> Don't use C API. The STL should provide you with enough API to use the proper C++ types, either std::string or std::string_view in C++17 if possible.
Sometimes you're working with C API that gives you back a char * that they've already allocated. AFAIK there isn't a way to create an std::string out of that without a copy.
> you can't static_cast<> a pointer
You can static_cast a void * into other kinds of pointers.
> use std::array
Do you mean std::vector and at()?
No, std::array was added in C++11: http://en.cppreference.com/w/cpp/container/array
array::at is just as mandatory as vector::at IMO.
Moreover, you can use static_cast for downcasts (from the parent class to child class) - without runtime costs of dynamic_cast. static_cast is not safe (it doesn't perform runtime checks), but reinterpret_cast is even worse (it doesn't perform even compile-time checks).
You can use std::string_view, Google's StringPiece or llvm::StringRef.
> Rules to ensure memory safety
These "rules" only protect you against object's lifetime issues, not overflow / underflows, and other kind of memory issues.
> ‘owning’ pointers are obtained only from operator new
no, you shall be using std::make_{unique,shared}(...) which will protect you against leaking memory if exceptions are raised.
> Calling a function passing the pointer as a parameter, is ok.
Correct, but you can still shoot yourself in the foot. Best is to pass a [const] reference to the function called.
> This only leaves us with functions such as strchr()
Don't use C API. The STL should provide you with enough API to use the proper C++ types, either std::string or std::string_view in C++17 if possible.
> and also prohibits C-style cast and static_cast with respect to pointers
IIRC, you can't static_cast<> a pointer, you'd have to reinterpret_cast<> it, which the document does mention.
> For arrays, we can always store the size of the array within our array collection, and check the validity of our ‘safe iterator’ before dereferencing/indexing
use std::array.