How to properly deal with dynamically allocated memory