Bug: Potential wrong alignment
The pointer returned by malloc() and friends meets the alignment needs for all standards typetypes.
OP's code takes the address and offsets it by the size of 2 int. This is likely an agreeable alignment for many types, but not specified so. Consider a complex long double which may need an alignment of 16 and 2 int is 8.
A solution is to use a header struct based with a FAM which will add any required padding.
// #define RAW_LIST(list) ((int*) list) - 2
// #define FIRST_ELEMENT(list) ((int*) list) + 2
struct head {
int len;
int cap;
max_align_t data[];
}
#define RAW_LIST(list) (((struct head*) list) - 1)
#define FIRST_ELEMENT(list) (((struct head*) list) + 1)
struct header *memory = malloc(sizeof *mmemory + itemSize*initialCapacity;itemSize*initialCapacity);
Use a final () around these macro definitions.
I'd use size_t rather than int.
The header also cleans up other code too. and makes it more flexible to add a uniform element size member.
Simplify interface
I see little value in the int initialCapacity parameter. 0 is fine.
Consider size of empty list
When a collection type is use a lot, the existence of many instances of empty lists is possible. Based on my experience, such collections are often empty.
Consider a pointer of NULL as empty and adjust code accordingly. It can save quite a bit of space.
This also allows clean initialization:
struct KCR_Vec3* vectors = 0;