The example in your book is confusing!
Actually, the compiler does "know" how much memory to allocate with char. But, wiith dynamic allocation you can say:
new unsigned char[x]; // Now, the compiler might not know what x is.
You cannot do that without using dynamic allocation (unless x is a constant/macro defined at compile-time.)
Also, that statement could be in a loop, and the compiler might not know how many times you are going to execute the loop!!!
For example, if you need to add a new name to a database... you might not know how many names the database will to hold when you write the program.
Perhaps the book should have said:
...the compiler doesn’t need to know how much storage...
...the compiler doesn’t care how much storage...