My strategy in c is as soon as I write the word "malloc" I figure out where to put the free.
No, it isn't; you don't know how quickly the program will terminate, in general, and it only takes one program running longer than you expect to eat a horrible amount of RAM.
(I do think it's bad style, and would never write this program this way.)
[1] Assuming you stay away from the Zombie^W Network File System. But NFS mounts going away is bad news anyway, this program holding an extra KB of swappable memory doesn't really intensify the pain.
The downside to calling free(), apart from performance (malloc/free are extremely expensive), is that messing them up creates bugs that are much worse than simply holding on to some allocator metadata until the program hits exit().
Messing them up exposes bugs that are likely to bite you in other ways. If you can't get malloc()/free() right, you don't really 'get' the flow control/data flow through your program yet and that is a problem.
Virtually no large project has ever gotten malloc/free completely right in its first revision; for the past 20 years or so, most projects get this wrong to the tune of "remote code execution".