ob_start() (Output Buffering start) le dice a PHP que no envie nada al navegador de lo que esta adentro de esa declaracion (tienes usar luego
ob_end_flush). Por lo tanto primero procesa todo y luego envia la informacion al navegador. Por eso resuelve el problema cuando tienes que llamar algun header obligatoriamente despues de algun codigo que puede estar enviando informacion al navegador. Pero te sugiero que mejor coloques el cookie al principio y luego llames el codigo