Main Content

CERT C++: MEM57-CPP

Avoid using default operator new for over-aligned types

Description

Rule Definition

Avoid using default operator new for over-aligned types.1

Polyspace Implementation

The rule checker checks for Operator new not overloaded for possibly overaligned class.

Examples

expand all

Issue

Operator new not overloaded for possibly overaligned class occurs when you do not adequately overload operator new/new[] and you use this operator to create an object with an alignment requirement specified with alignas. The checker raises a defect for these versions of throwing and non-throwing operator new/new[].

  • void* operator new(std::size_t size)

  • void* operator new(std::size_t size, const std::nothrow_t&)

  • void* operator new[](std::size_t size)

  • void* operator new[](std::size_t size, const std::nothrow_t&)

The use of alignas indicates that you do not expect the default operator new/new[] to satisfy the alignment requirement or the object, and that the object is possibly over aligned. A type is over aligned if you use alignas to make the alignment requirement of the type larger than std::max_align_t. For instance, foo is over aligned in this code snippet because its alignment requirement is 32 bytes, but std::max_align_t has an alignment of 16 bytes in most implementations.

struct alignas(32) foo {
  char elems[32];
};

Operator new not overloaded for possibly overaligned class raises no defect if you do not overload the operator new/new[] and you use version C++17 or later of the Standard. The default operator new/new[] in C++17 or later supports over alignment by passing the alignment requirement as an argument of type std::align_val_t, for instance void* operator new(std::size_t size, std::align_val_t alignment).

Risk

The default operator new/new[] allocates storage with the alignment requirement of std::align_val_t at most. If you do not overload the operator when you create an object with over aligned type, the resulting object may be misaligned. Accessing this object might cause illegal access errors or abnormal program terminations.

Fix

If you use version C++14 or earlier of the Standard, pass the alignment requirement of over aligned types to the operator new/new[] by overloading the operator.

Example - Allocated Memory Is Smaller Than Alignment Requirement of Type foo
#include <new>
#include <cstdlib>
#include <iostream>

struct alignas(64) foo {
    char elems[32];
};

foo*  func()
{
    foo*  bar = 0x0;
    try {
        bar =  new  foo ; //Noncompliant
    } catch (...) { return nullptr; }
    delete bar;
}

In this example, structure foo is declared with an alignment requirement of 32 bytes. When you use the default operator new to create object bar, the allocated memory for bar is smaller than the alignment requirement of type foo and bar might be misaligned.

Correction — Define Overloaded Operator new to Handle Alignment Requirement of Type foo

One possible correction, if you use C11 stdlib.h or POSIX-C malloc.h, is to define an overloaded operator new that uses aligned_alloc() or posix_memalign() or to obtain storage with the correct alignment.

#include <new>
#include <cstdlib>
#include <iostream>

struct alignas(64) foo {
    char elems[32];
    static void* operator new (size_t nbytes)
    {
        if (void* p =
                ::aligned_alloc(alignof(foo), nbytes)) {
            return p;
        }
        throw std::bad_alloc();
    }
    static void operator delete(void *p) {
        free(p);
    }
};

foo*  func()
{
    foo*  bar = 0x0;
    try {
        bar =  new  foo ;
    } catch (...) { return nullptr; }
    delete bar;
} 

Check Information

Group: Rule 06. Memory Management (MEM)

Version History

Introduced in R2019b


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.