There is one additional major difference, mostly important for lazy (bad) programmers: malloc() does resource tracking. You can return from the program without explicitely calling free() and the startup code will return all allocated memory. Each AllocVec() *must* be matched by a FreeVec().
Advanced programmer should prefer AllocPooled() call over AllocMem()/AllocVec() calls IMO. No more memory leaks (just remember DeletePool() on exit) and you also avoid memory fragmentation when doing small allocations.