[NSFoo alloc] allocates the right amount of memory for an instance of class NSFoo, sets all bits to zero, fills in everything that is needed so that it's not raw memory but an object of class NSFoo, and sets the retain count to 1. (Difference to C++: C++ doesn't initialise the memory to zero, and if you use inheritance then the object starts as an instance of the base class, executes the constructor while being an instance of the base class, then is turned into an instance of the derived class and executes the constructor of the derived class. In Objective-C, an object is already a member of the derived class while the init method executes).
[myobject release] first checks whether the object is a special kind of object that never gets released, like @"mystring" is an object that you can release as often as you like, it never goes away. If it is not one of those special objects then "release" checks the retain count. If the retain count is greater than 1 then it subtracts 1 from the retain count. If the retain count is equal to 1, then it calls the [myobject dealloc] method, and then deallocates the memory.
Allocating and deallocating are done with a variant of malloc and free. The "dealloc" method should better not modify the object's retain count; it might be legal to do retain/release in pairs in the dealloc method (don't do it unless you find official documentation that says you can); an unmatched "retain" inside the dealloc method is a bad idea, and an unmatched "release" is a very, very, very bad idea.