Also, one of the horrible things about low-level languages. Ponter arithmetic is a veritable error-generating machine, because it requires, well, arithmetic, and detailed knowledge about the exact shape of your data structure, things which should be abstracted away as soon as possible. For the same reason, pointer arithmetic can make code very difficult to read. The core problem is that it results in arithmetic errors causing hard-to-track semantic errors, i.e. you don't just get a wrong number somewhere, the program behaves totally different from the way it should, trashing your whole data structure, etc.

That being said, pointer arithmetic is quite necessary and valuable to have in low-level languages, because it allows for very efficient handling of data structures. This is especially important in the field of I/O, where it saves a lot of copying: you can process that byte array directly instead of parsing it into a few dozen objects, additionally incurring a large overhead for object creation.