Yes it can. But it's nearly impossible to handle such cases properly. That's why checking each allocation manually is a bad idea. Other languages do this better - they provide nice abstractions, but if something fails, the language runtime terminates the process. The result is the same, but has much less friction.
Also on some systems (like Linux) memory allocation may not fail, but the "allocated" memory may not be available and a program can crash accessing this memory.