* Typo in the header file (SIZE versus CAPACITY).
* No error checking on malloc() or realloc() return.
* Out of bounds access is a programmer error, so you should call abort() and not exit(). Alternatively, assert() is fine too.
* Potential integer overflow for capacity field (size field can't overflow because capacity overflows first). On a 64-bit non-ILP64 system, resizing to a capacity of 2^31 elements will request a buffer of 0xfffffffe00000000 bytes, assuming sizeof(int) is 4.
* A 32-bit version could theoretically get an overflow, but only if a 2^31 byte allocation is successful... the next larger allocation will be for 0 bytes.
Edit: As someone pointed out in the comments, arr[271] is the 272nd element, whereas the article claims it is the 270th element.
Further notes:
If you end up implementing a lot of these, invest in a consistent naming scheme for the fields. For example, map, mapsz, mapalloc; then data, datasz, dataalloc.
You can also try writing generics in C but I strongly recommend just switching to C++ (or some other language) if the boilerplate code bothers you. I believe that std::vector was the biggest reason for GCC's switch to C++ internally.