Most languages from the past 40 years have either been interpreted or JIT'ed. While this has many benefits, it also creates a walled garden where software can only talk to other software from the same ecosystem. You have to make a conscious effort to make Java code talk to Python code, for example.
Systems-level programmers are more interested in targeting the "least common denominator", writing code that runs directly on the CPU without any outside help apart from standard OS calls. This is why almost every language has an FFI bridge that can talk to plan C - C is the least common denominator on any given system, so everybody knows how to talk to it.
To have a shot at replacing C, a new language needs to operate at the same level of the stack, relying only on the raw CPU and OS. C++ can do this, but it doesn't offer much safety benefit over C. ObjectiveC is the same.
This is why Go and Rust are so exciting. They are the first languages in a long time that actually run at the same level as C. Rust has the additional benefit of not even requiring a garbage collector, so it can be used in embedded microcontrollers and OS kernels. Go's garbage is a downside, but maybe not a fatal one.
Besides, even if we had hardware bounds checking, you would still need a language that could take advantage of that. C's memory model is too loose, so there is no place to even hook the bounds-checker in. Think about this:
struct Data {
char name[20];
void *next; // Points to another `Data` instance
}
If you try writing a string longer than 20 characters to `((Data *)data.next)->name`, there is no way the compiler could ever type-check that, or tell the hardware bounds checker where the limit is. This is why C has to go.