size_t is the type that should be used for array indexing when you work with a relatively generic arrays. I.e. when you have just an array of abstract chars, ints or something else.
When you are working with a specific array, i.e. an array that contains some elements specific for your application, you should normally already have a "type of choice" to count or to index the entities of that type in your application. That's the type you should use. For example, if some array contains the records for company employees, then you should already have a "type of choice" in your program that you use to designate the "quantity of employees". That's the type you should use for indexing arrays of employee records. It could be unsigned int, it could be employee_count_t or something like that. Using a naked size_t for that purpose is a design error.
Note also, that size_t is a type not immediately intended for array indexing. It is a type intended to represent the size of the largest object in the program. It "works" for arrays by transitivity: arrays are objects, hence size_t is always enough to index an array. However, when you design a program it makes more sense to think in terms of generic containers, instead of thinking in terms of specific arrays. Today it might be an array, tomorrow you might have to switch to a linked list or a tree instead. In general case, the range of size_t is not sufficient to represent the number of elements in an abstract container, which is why size_t in such cases is not a good choice.