It is definitely invalid to use either of *height
or *width
after free. However, it is also invalid to use an object in general after it has been destroyed. Since the freeing of the pointers happen in the destructor, it is acceptable.
However, your code breaks the "rule of three": When a class allocates its own memory, it needs to have a copy constructor and an assignment operator, or you will either leak memory or get "use of memory that you shouldn't be using" (or both).
Consider:
...
CRectangle r1(10,25);
CRectangle r2(10,26);
CRectangle bigger(0,0);
if (r1.area() > r2.area())
bigger = r1;
else
bigger = r2;
{
CRectangle r3(200, 300);
r1 = r3;
} // r3 is destroyed here.
cout << r1.area() << endl; // Bang, using freed memory.
In your copy constructor and assignment operator, you need to make the relevant free of the old data and allocate new, depending on what you are doing.
[Of course, it's a complete waste of memory space and time to do this for two integers - even the best memory allocation I know of will use five times more memory this way than just having two integers in the class.]