Memory corruption attacks against software written in C or C++ are still prevalent and remain a significant cause of security breaches. Defenses providing full memory safety remain expensive, and leaner defenses only addressing control-flow data are insufficient. We introduce memory categorization, an approach to separate data based on attacker control to mitigate the exploitation of memory corruption vulnerabilities such as use-after-free and use-after-return. MemCat implements this approach by: (i) providing separate memory allocators for different data categories, (ii) categorizing the use of memory allocations, (iii) changing allocations to take advantage of the categorization. We demonstrate the effectiveness of MemCat in a case study on actual vulnerabilities in real-world programs. We further show that, although our prototype implementation causes a high overhead in two edge cases, in most cases the performance hit remains negligible, with a median overhead of less than 3% on the SPEC benchmark suite.