Unless you are writing a trivial program, one should avoid stand-alone bare-bones mallocs on the top-level of your program.
Now it may seem that I am about to go beyond the scope of your question, but in fact, your question begs the broader answer, because, to do our best programming, we must always be aware how our sharp, narrowly focused concern fits in the larger scheme of things, and that is what I wish to address.
The first concern when dealing with mallocs are memory leaks. You did a great job for the first part of that problem by making sure that on failure they got deallocated. Just be aware that there are several additional concerns down the road.
The biggest and most frequent problems with use of mallocs is that it is very easy to end up with memory leaks. Again, I can't emphasize this too much. This should be the number one concern every time you use mallocs.
Compared to this number one issue, branching style, as long as it is structured, and you have made some effort to be clean and direct, is of secondary importance to handling of memory leaks (e.g., an English accent is just as good as an Irish accent and speaking well is a bit more important, but it is much less important than whether you exhibit criminal behavior.)
There are many good ways to deal with good malloc writing.
For example, as long as you are not dealing with interrupt events or other advanced error handling concerns, let’s look at a good way to work with mallocs.
- Make your programs strictly structured.
- Write allocation procedures that do all the right things for malloc in pairs. One procedure to allocate memory for a certain set of scenarios, and another procedure that will deallocate exactly the same memory for the same set of scenarios in exactly a reverse fashion. These can be written in many ways. But again that the job gets done perfectly is the most important. Once you debug the procedures, you don't have to worry about whether it was done correctly because you will know. That little piece of knowledge is invaluable to how you use the procedures. You want to be able to count on them.
- Topologically in your program, make sure that at any point where memory is allocated, that every path of execution after the allocation will at some point execute the corresponding deallocation procedure regardless of all conditionals and loops.
- Now you written a good set of procedures you can pull them out to apply to the more advanced aspects of mallocing down the road.
You want to design these paired procedures well enough that you know for a fact that after properly executing both of them, that no memory associated with the pair of transactions is still allocated. Again style has some importance, but there are many ways to write these. What is really important is the salient fact of making sure there aren't any memory leaks. That is the most important.
Here is a nice little story. Once I was on a contract that when I came on the scene a serious memory leak problem had been around a few months which was not getting fixed. I used the methods that I described to you and within the day I went through the whole program and structured all the mallocs.
A couple of days later, the problem happened again. I knew that could not be, because I had checked all the structured paths through the program, but there it was. Because I was able to know that it was correct because of the systematic application of the simple principles of pairing the mallocs, and following the topological flow of the program, I knew it made sense to look elsewhere. After some analysis, I decided the only possibility is that there were compound interrupts touching the same memory locations which were destroying the structuring of the program. So I set a few breakpoints that would get triggered if the problem occurred, and sure enough I got a hit.
I looked at the stack and sure enough, one interrupt fudged the memory allocation and the other stepped on it. Having identified the two events, I just added a mutual exclusion between the two events. This took about 10 minutes from beginning to finish and fixed several months worth of problems.
There isn't any way that I could have found the problem without doing my mallocs in the right way in a systematic fashion. And BTW, I don't have any idea what style I used with the conditionals, and that didn't really matter much. Did it?