Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Replaced effective size with element count

...

For the purposes of this rule, the effective size element count of a pointer is the size of the object to which it points, expressed by the number of elements which are valid to access.

...

Code Block
int arr[5];
int *p = arr;

unsigned char *p2 = (unsigned char *)arr;
unsigned char *p3 = arr + 2;
void *p4 = arr;

the effective size element count of the pointer p is sizeof(arr) / sizeof(*arr[0]), that is, 5The effective size of The element count of the pointer p2, is sizeof(arr), that is, 20 (on platforms where sizeof(int) == 4).  The effective size element count of the pointer p3 is 12 (on platforms where sizeof(int) == 4), because p3 points two elements past the start of the array arrThe effective size of The element count of p4 is treated as though it were unsigned char * instead of void *, and so is the same as p2.

...

bsearch()bsearch_s()qsort()qsort_s()
fread()fwrite()  

Noncompliant Code Example (

...

Element Count)

In this noncompliant code example, the incorrect effective size is incorrect element count is used in a call to wmemcpy().  The sizeof operator returns the size expressed in bytes, but wmemcpy() uses an effective size of an element count based on wchar_t *.

Code Block
bgColor#FFcccc
#include <string.h>
#include <wchar.h>
 
static const char str[] = "Hello world";
static const wchar_t w_str[] = L"Hello world";
void func(void) {
  char buffer[32];
  wchar_t w_buffer[32];
  memcpy(buffer, str, sizeof(str));
  wmemcpy(w_buffer, w_str, sizeof(w_str));
}

Compliant Solution (

...

Element Count)

When using functions that operate on pointed-to regions, programmers must always express the integer size in terms of the effective size expected the element count expected by the function.  For instance, memcpy() expects the effective size expressed the element count expressed in terms of void *, but wmemcpy() expects the effective size expressed the element count expressed in terms of wchar_t *.  Instead of using the sizeof operator, calls to return the number of elements in the string are used, which matches the expected effective size for expected element count for the copy functions.

Code Block
bgColor#ccccff
#include <string.h>
#include <wchar.h>
 
static const char str[] = "Hello world";
static const wchar_t w_str[] = L"Hello world";
void func(void) {
  char buffer[32];
  wchar_t w_buffer[32];
  memcpy(buffer, str, strlen(str) + 1);
  wmemcpy(w_buffer, w_str, wcslen(w_str) + 1);
} 

...

For calls that take a pointer and an integer size, the given size should not be greater than the effective size of the element count of the pointer.  This compliant solution ensures that the value of n is not greater than the size of the dynamic memory pointed to by the pointer p:

...

In this noncompliant code example, the effective size of the element count of the array a is ARR_SIZE elements.  Because memset expects a byte count, the size of the array is scaled incorrectly by sizeof(int) instead of sizeof(float), which can form an invalid pointer on architectures where sizeof(int) != sizeof(float).

...

In this compliant solution, the effective size required the element count required by memset is properly calculated without resorting to scaling.

...

For calls that take a two pointers and an integer size, the given size should not be greater than the effective size element count of either pointer.  This compliant solution ensures that n is equal to the size of the character array:

...

In this noncompliant code example, the size of struct obj is assumed to be eight bytes to account for padding.  However, the padding is dependent on the target architecture as well as compiler settings, so this may be the incorrect effective sizesize of the object, which then yields the incorrect element count.

Code Block
bgColor#FFcccc
#include <stdio.h>
 
struct obj {
  char c;
  int i;
};
 
void func(FILE *f, struct obj *objs, size_t numObjs) {
  if (numObjs != fwrite(objs, 8, numObjs, f)) {
    /* Handle error */
  }
}

...

For calls that take a pointer and two integers, generally accept one integer representing the size of an individual object, and a second integer representing the number of objects in the array.  The resulting product of the two integers should not be greater than the effective size of the element count of the pointer were it expressed as an unsigned char *.   See INT30-C. Ensure that unsigned integer operations do not wrap for more information.

...