The language makes all the difference because defaults matter. As someone said once, you can write C in any language. You can even do a heartbleed in python - just create one big buffer, do your own allocator, and pass (buffer, index) everywhere instead of proper object.
But would anyone do this? No. If you are writing pool-based packet processor in Python, you'd deal in buffers (safe from overread), in C# you'd return Span/Memory (safe from overread) and only in C you'd return overread-prone raw pointer.
Not that you can blame programmers in this case - C simply lacks the facilities for safe memory access, such as bounded pointers or spans. And you can't really blame it on custom allocator - malloc() would have had the same problem.
But would anyone do this? No. If you are writing pool-based packet processor in Python, you'd deal in buffers (safe from overread), in C# you'd return Span/Memory (safe from overread) and only in C you'd return overread-prone raw pointer.
Not that you can blame programmers in this case - C simply lacks the facilities for safe memory access, such as bounded pointers or spans. And you can't really blame it on custom allocator - malloc() would have had the same problem.