Pointer arithmetic is only appropriate when the pointer argument refers to an array ARR37-C. Do not add or subtract an integer to a pointer to a non-array object. When performing pointer arithmetic, the size of the value to add or subtract to a pointer is automatically scaled to the size of the type of the referenced array object. Adding or subtracting a scaled integer value to a pointer is insecure because it may result in a pointer that does not point to an element within or one past the end of the array. This is contraindicated by ARR38-C. Do not add or subtract an integer to a pointer if the resulting value does not refer to a valid array element.
| Violations of this guidelines are indicated when a pointer to an array is added to the result of the {{sizeof}} operator or {{offsetof}} macro which return a size and offset, respectively.  However, adding an array pointer to the number of array elements, for example by using the {{arr\[sizeof(arr)/sizeof(arr\[0\])\])}} idiom, is allowed, provided that {{arr}} refers to an array and not a pointer. | 
In this noncompliant code example, the pointer buf is added to sizeof(buf).  This is noncompliant because sizeof(buf) is scaled by int and is scaled again when added to buf.
| int buf[INTBUFSIZE];
int *buf_ptr = buf;
while (havedata && buf_ptr < (buf + sizeof(buf))) {
    *buf_ptr++ = parseint(getdata);
}
 | 
In this noncompliant code example, skip is added to the pointer s.  However, skip represents the byte offset of ull_2 in struct big.  When added to s, skip is scaled by the size of struct big.
| struct big {
  unsigned long long ull_1; /* typically 8 bytes */
  unsigned long long ull_2; /* typically 8 bytes */
  unsigned long long ull_3; /* typically 8 bytes */
  int si_4;                 /* typically 4 bytes */
  int si_5;                 /* typically 4 bytes */
};
/* ... */
size_t skip = offsetof(struct big, ull_2);
struct big *s = (struct big *)malloc(sizeof(struct big));
if (!s) {
  /* Handle malloc error */
}
memset(s + skip, 0, sizeof(struct big) - skip);
/* ... */
free(s);
s = NULL;
 | 
In this noncompliant code example, wcslen(error_msg) * sizeof(wchar_t) bytes are scaled by the size of wchar_t when added to error_msg.
| /* ... */ wchar_t error_msg[WCHAR_BUF]; wcscpy(error_msg, L"Error: "); fgetws(error_msg + wcslen(error_msg) * sizeof(wchar_t), WCHAR_BUF - 7, stdin); /* ... */ | 
| \[[Dowd 06|AA. Bibliography#Dowd 06]\] Chapter 6, "C Language Issues" \[[ISO/IEC PDTR 24772|AA. Bibliography#ISO/IEC PDTR 24772]\] "HFC Pointer casting and pointer type changes" and "RVG Pointer Arithmetic" \[[MISRA 04|AA. Bibliography#MISRA 04]\] Rules 17.1-17.4 \[[MITRE 07|AA. Bibliography#MITRE 07]\] [CWE ID 468|http://cwe.mitre.org/data/definitions/468.html], "Incorrect Pointer Scaling" \[[Murenin 07|AA. Bibliography#Murenin 07]\] |