Two or more new expressions evaluated as arguments of the same call
ID |
c.maintainability.multiple_allocations_in_one_statement |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Resource Management |
Language |
C / C++ |
Description
This call evaluates two or more new expressions as its own arguments. The standard does not fix the order in which sibling arguments are evaluated, so if the second allocation throws std::bad_alloc after the first one already succeeded, nothing owns that first pointer yet and it leaks. Allocate each object into a smart pointer (std::make_unique/std::make_shared) in its own statement before the call, so ownership is established immediately after each allocation.
Rationale
This call evaluates two or more new expressions as its own arguments. The standard does not fix the order in which sibling arguments are evaluated, so if the second allocation throws std::bad_alloc after the first one already succeeded, nothing owns that first pointer yet and it leaks. Allocate each object into a smart pointer (std::make_unique/std::make_shared) in its own statement before the call, so ownership is established immediately after each allocation.
The following code illustrates the pattern detected by this rule:
struct Widget {
Widget(int x, int y);
};
void pair(Widget *a, Widget *b);
void leaks_on_second_throw()
{
// FLAGGED: Two or more `new` expressions evaluated as arguments of the same call
pair(new Widget(1, 2), new Widget(3, 4));
}