Do yourself a favor and just use int if it's an integer. Otherwise it gets messy once you come across function overloads that expect char objects to actually be characters (e.g., formatted stream IO):
int hello = 52;
If you really need to save some memory, you can use unsigned char directly:
unsigned char hello = 52;
If, for whatever reasons, you want to limit the lifetime of the object to a smaller scope, you can just introduce another level of nesting:
{
unsigned char hello = 52;
} // no need to delete here, because the object is destroyed automatically
Note that you actually use more memory, when you declare a pointer (that is likely to be 64-bits wide nowadays) and dynamically allocate memory to hold a byte elsewhere.
If you really want to extend your object's lifetime beyond the current scope, you could use a smart pointer instead, to prevent issues like leaking memory or double free.
std::unique_ptr<char> hello = std::make_unique<char>(52);
But do note that this is usually a hassle and most often not necessary at all, especially for objects this small. Just declare a local variable, copy it around as needed, and be done with it.
Besides that, you need to dereference the pointer to access the object the pointer points to:
unsigned char * p = new unsigned char;
*p = 52;
delete p;