Good advice. Integer arithmetic is one of the trickiest aspects of C, and dangerous in combination with the manual memory management. For more information, see the free chapter of TAOSSA: http://pentest.cryptocity.net/files/code_analysis/Dowd_ch06....
There are (were) a couple bugs in the example code. Here are a some guidelines that will help avoid those, and most problems with integer operations and the heap in general.
First, don't mix unsigned and signed types in arithmetic; and always prefer the size_t type for variables representing the size of an object.
Second, check for overflow before an operation, not after, like so:
if (size > SIZE_MAX / 2) {
goto error;
}
newsize = size * 2;
Third, always double-check the arguments to memory allocation functions, especially for zero, because the result is not always well defined. if (size >= SIZE_MAX - n) {
goto error;
}
foo = malloc(size + n);
foo[size] = ...;