Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: minor edits; reviewed

...

Function

Initialization

aligned_alloc()

Does not perform initialization

calloc()

Zero-initializes allocated memory

malloc()

Does not perform initialization

realloc()

Copies contents from original pointer; may not initialize all memory

Uninitialized automatic variables or dynamically allocated memory has has indeterminate value, which for objects of some types can be a trap representation. Reading uninitialized memory is undefined behavior (see undefined behavior 10 and undefined behavior 12 in Annex J of the C Standard); it can cause a program to behave in an unexpected manner and provide an avenue for attack. In most many cases, compilers issue a warning diagnostic message when reading uninitialized variables. See MSC00-C. Compile cleanly at high warning levels for more information.

...

In this noncompliant code example, the set_flag() function is intended to set the parameter, sign_flag, to the sign of number. However, the programmer neglected to account for number being the case where number is equal to 0. Because the local variable sign is uninitialized when calling set_flag(), and is never written to by set_flag(), the comparison operation exhibits undefined behavior when reading sign.

...

This defect results from a failure to consider all possible data states. ( See MSC01-C. Strive for logical completeness.) Once the problem is identified,  for more information.

Compliant Solution (Return-by-Reference)

...

Code Block
bgColor#ccccff
langc
void set_flag(int number, int *sign_flag) {
  if (NULL == sign_flag) {
    return;
  }

  /* Account iffor (number >=being 0) { */*
 Account forif (number being>= 0) { */
    *sign_flag = 1;
  } else {
    *sign_flag = -1;
  }
}

int is_negative(int number) {
  int sign = 0;   /* Initialize for defense-in-depth */
  set_flag(number, &sign);
  return sign < 0;
}

...

In this noncompliant code example, the function mbrlen() is passed the address of an automatic mbstate_t object that has not been properly initialized. This leads to is undefined behavior because mbrlen() dereferences and reads its third argument. See undefined behavior 200 in Annex J of the C Standard.

...

Before being passed to a multibyte conversion function, an mbstate_t object must be either initialized to the initial conversion state or set to a value that corresponds to the most recent shift state by a prior call to a multibyte conversion function. The This compliant solution sets the mbstate_t object to the initial conversion state by setting it to all zeros.

...

Code Block
bgColor#FFCCCC
langc
#include <stdlib.h>

#include <stdio.h>
 
int *resize_array(int *array, size_t count) {
  if (0 == count) {
    return 0;
  }
 
  int *ret = (int *)realloc(array, count * sizeof(int));
  if (!ret) {
    free(array);
    return 0;
  }
 
  return ret;
}
 
void func(void) {
  enum { OLD_SIZE = 10, NEW_SIZE = 20 };
 
  int *array = (int *)malloc(OLD_SIZE * sizeof(int));
  if (0 == array) {
    /* Handle error */
  }
 
  for (intsize_t i = 0; i < OLD_SIZE; ++i) {
    array[i] = i;
  }
 
  array = resize_array(array, NEW_SIZE);
  if (0 == array) {
    /* Handle error */
  }
 
  for (intsize_t i = 0; i < NEW_SIZE; ++i) {
    printf("%d ", array[i]);
  }
}

...

In this compliant solution, the resize_array() helper function takes a second parameter for the old size of the array so that it can initialize any elements that are newly allocatedany newly allocated elements.

Code Block
bgColor#ccccff
langc
#include <stdlib.h>
#include <stdio.h> 
 
int *resize_array(int *array, size_t old_count,
                  size_t new_count) {
  if (0 == new_count) {
    return 0;
  }
 
  int *ret = (int *)realloc(array, new_count * sizeof(int));
  if (!ret) {
    free(array);
    return 0;
  }
 
  if (new_count > old_count) {
    for (size_t i = new_count - old_count;
         i < new_count; ++i) {
      ret[i] = 0;
    }
  }
 
  return ret;
}
 
void func(void) {
  enum { OLD_SIZE = 10, NEW_SIZE = 20 };
 
  int *array = (int *)malloc(OLD_SIZE * sizeof(int));
  if (0 == array) {
    /* Handle error */
  }
 
  for (intsize_t i = 0; i < OLD_SIZE; ++i) {
    array[i] = i;
  }
 
  array = resize_array(array, OLD_SIZE, NEW_SIZE);
  if (0 == array) {
    /* Handle error */
  }
 
  for (intsize_t i = 0; i < NEW_SIZE; ++i) {
    printf("%d ", array[i]);
  }
}

...