malloc just hands you back some memory that it has handy. If it's newly allocated from the system, odds are that it'll be zeroed. (On most OSes these days freshly minted process memory comes pre-zeroed since it's no more expensive to hand you zeroed memory as any other type) malloc keeps a free list, though, and when you free() some memory, you may get that same chunk back later, with whatever gook might be in it.
If you want guaranteed zeroed memory, use calloc() instead. It zeroes the memory before it's handed to you, and generally in the way most efficient for the OS you're on.