Main Content

CERT C: Rec. MEM02-C

Immediately cast the result of a memory allocation function call into a pointer to the allocated type

Description

Rule Definition

Immediately cast the result of a memory allocation function call into a pointer to the allocated type.1

Polyspace Implementation

The rule checker checks for Wrong allocated object size for cast.

Examples

expand all

Issue

Wrong allocated object size for cast occurs during pointer conversion when the pointer’s address is misaligned. If a pointer is converted to a different pointer type, the size of the allocated memory must be a multiple of the size of the destination pointer.

Risk

Dereferencing a misaligned pointer has undefined behavior and can cause your program to crash.

Fix

Suppose you convert a pointer ptr1 to ptr2. If ptr1 points to a buffer of N bytes and ptr2 is a type * pointer where sizeof(type) is n bytes, make sure that N is an integer multiple of n.

See examples of fixes below.

If you do not want to fix the issue, add comments to your result or code to avoid another review. See:

Example - Dynamic Allocation of Pointers
#include <stdlib.h>

void dyn_non_align(void){
    void *ptr = malloc(13);
    long *dest;

    dest = (long*)ptr; //defect //Noncompliant
}

In this example, the software raises a defect on the conversion of ptr to a long*. The dynamically allocated memory of ptr, 13 bytes, is not a multiple of the size of dest, 4 bytes. This misalignment causes the Wrong allocated object size for cast defect.

Correction — Change the Size of the Pointer

One possible correction is to use a pointer size that is a multiple of the destination size. In this example, resolve the defect by changing the allocated memory to 12 instead of 13.

#include <stdlib.h>

void dyn_non_align(void){
    void *ptr = malloc(12);
    long *dest;

    dest = (long*)ptr;
}
Example - Static Allocation of Pointers
void static_non_align(void){
    char arr[13], *ptr;
    int *dest;

    ptr = &arr[0];
    dest = (int*)ptr; //defect //Noncompliant
}

In this example, the software raises a defect on the conversion of ptr to an int* in line 6. ptr has a memory size of 13 bytes because the array arr has a size of 13 bytes. The size of dest is 4 bytes, which is not a multiple of 13. This misalignment causes the Wrong allocated object size for cast defect.

Correction — Change the Size of the Pointer

One possible correction is to use a pointer size that is a multiple of the destination size. In this example, resolve the defect by changing the size of the array arr to a multiple of 4.

void static_non_align(void){
    char arr[12], *ptr;
    int *dest;

    ptr = &arr[0];
    dest = (int*)ptr;
}
Example - Allocation with a Function
#include <stdlib.h>

void *my_alloc(int size) { 
    void *ptr_func = malloc(size); 
    if(ptr_func == NULL) exit(-1); 
    return ptr_func; 
}

void fun_non_align(void){
    int *dest1;
    char *dest2;

    dest1 = (int*)my_alloc(13);  //defect //Noncompliant
    dest2 = (char*)my_alloc(13); //not a defect
}

In this example, the software raises a defect on the conversion of the pointer returned by my_alloc(13) to an int* in line 11. my_alloc(13) returns a pointer with a dynamically allocated size of 13 bytes. The size of dest1 is 4 bytes, which is not a divisor of 13. This misalignment causes the Wrong allocated object size for cast defect. In line 12, the same function call, my_alloc(13), does not call a defect for the conversion to dest2 because the size of char*, 1 byte, a divisor of 13.

Correction — Change the Size of the Pointer

One possible correction is to use a pointer size that is a multiple of the destination size. In this example, resolve the defect by changing the argument for my_alloc to a multiple of 4.

#include <stdlib.h>

void *my_alloc(int size) { 
    void *ptr_func = malloc(size); 
    if(ptr_func == NULL) exit(-1); 
    return ptr_func; 
}

void fun_non_align(void){
    int *dest1;
    char *dest2;

    dest1 = (int*)my_alloc(12); 
    dest2 = (char*)my_alloc(13); 
}

Check Information

Group: Rec. 08. Memory Management (MEM)

Version History

Introduced in R2019a


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.