C doesn't care what the pointer is to. If sizeof(char) is 1, and sizeof(int) is 4, then malloc(sizeof(int)) is the same as malloc(sizeof(char)*4). Note malloc returns a void * anyway. Since C doesn't really care what the pointer is to, you can always just cast buffers and it won't complain. Also note, you can do this cowboy style casting between types and C doesn't care, but it isn't really good form, and many compilers will complain about it.
so consider this code:
char* str = (char*)malloc(sizeof(char)*4);
int* intArr = (int*)malloc(sizeof(int));
//it is perfectly legal to do this:
char* intStr = (char*)intArr;
//or
printf("int char %c\n", ((char*)intArry)[2]);
//or
printf("int char %c\n, intStr[2]);
//or
printf("int char %c\n, intStr+2);
//or copy intArr into str
for (int i = 0; i < 4; i++) {str[i] = ((char*)intArr)[i];}
With that said, you should actually do this kind of stuff unless you really know how pointers work and what you are doing. Make sure you are doing it for the right reasons. Because it seems to work is not a right reason. :)
So for your code, you could "fix" it like this, but this code is still "very bad." scanf is not safe. It can easily overflow your namesArray buffer.
int numNames = getMaxNames(argv[1]);
char* namesArray = (char*)malloc(numNames * sizeof(int));
int i = 0;
for (i = 0; i< numNames; i++) {
scanf("%s", namesArray);
}
for (i = 0; i< numNames; i++) {
printf("%s\n", namesArray);
}
`
OR
int numNames = getMaxNames(argv[1]);
int* namesArray = (int*)malloc(numNames * sizeof(int));
int i = 0;
for (i = 0; i< numNames; i++) {
scanf("%s", (char*)namesArray);
}
for (i = 0; i< numNames; i++) {
printf("%s\n", (char*)namesArray);
}