 
                            The sizeof operator yields the size (in bytes) of its operand, which can be an expression or the parenthesized name of a type. However, using the sizeof operator to determine the size of arrays is error prone.
The sizeof operator is often used in determining how much memory to allocate via malloc(). However using an incorrect size is a violation of MEM35-C. Allocate sufficient memory for an object.
Noncompliant Code Example
...
In   this   noncompliant   code   example,   the   function  {{clear()}}  zeros   the   elements   in   an   array.   The   function   has   one   parameter   declared   as  {{int   array\[\]}}  and   is   passed   a   static   array   consisting   of   12  {{int}}  as   the   argument.   The   function  {{clear()}}  uses   the   idiom  {{sizeof(array)   /   sizeof(array\[0\])}}  to   determine   the   number   of   elements   in   the   array.   However,  {{array}}  has   a   pointer   type   because   it   is   a   parameter.   As   a   result,  {{sizeof(array)}}  is   equal   to   the  {{sizeof(int  \ *)}}.   For   example,   on   an   architecture   (such   as   IA-32)   where   the  {{sizeof(int)   ==   4}}  and   the  {{sizeof(int   *)   ==   4}},   the   expression  {{sizeof(array)   /   sizeof(array\[0\])}}  evaluates   to   1,   regardless   of   the   length   of   the   array   passed,   leaving   the   rest   of   the   array   unaffected.
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| 
void clear(int array[]) {
  for (size_t i = 0; i < sizeof(array) / sizeof(array[0]); ++i) {
     array[i] = 0;
   }
}
void dowork(void) {
  int dis[12];
  clear(dis);
  /* ... */
}
 | 
Wiki Markup 
When applied to a parameter declared to have array or function type, the
sizeofoperator yields the size of the adjusted (pointer) type . . . .
...
.
Compliant Solution
In this compliant solution, the size of the array is determined inside the block in which it is declared and passed as an argument to the function.:
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| void clear(int array[], size_t len) { for (size_t i = 0; i < len; i++) { array[i] = 0; } } void dowork(void) { int dis[12]; clear(dis, sizeof(dis) / sizeof(dis[0])); /* ... */ } | 
...
This  {{sizeof(array)   /   sizeof(array\[0\])}}  idiom   will   succeed   provided   the   original   definition   of  {{array}}  is   visible.
Noncompliant Code Example
In this noncompliant code example, the sizeof(a) does not equal 100 * sizeof(int). This is , because the sizeof operator, when applied to a parameter declared to have array or function typearray type, yields the size of the adjusted (pointer) type , even if the parameter declaration specifies a length.:
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| enum {ARR_LEN = 100}; void clear(int a[ARR_LEN]) { memset(a, 0, sizeof(a)); /* errorError */ } int main(void) { int b[ARR_LEN]; clear(b); assert(b[ARR_LEN / 2]==0); /* mayMay fail */ return 0; } | 
Compliant Solution
In this compliant solution, the size is specified using the expression len * sizeof(int).:
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| enum {ARR_LEN = 100}; void clear(int a[], size_t len) { memset(a, 0, len * sizeof(int)); } int main(void) { int b[ARR_LEN]; clear(b, ARR_LEN); assert(b[ARR_LEN / 2]==0); /* cannotCannot fail */ return 0; } | 
Risk Assessment
Incorrectly using the sizeof operator to determine the size of an array can result in a buffer overflow, allowing the execution of arbitrary code.
| Recommendation | Severity | Likelihood | Detectable | 
|---|
| Repairable | Priority | Level | 
|---|---|---|
| ARR01-C | High | 
| Probable | 
| No | 
| Yes | 
| P12 | L1 | 
Automated Detection
| Tool | Version | Checker | Description | 
|---|
| Section | 
|---|
| Splint | 
| Astrée | 
 | sizeof-array-parameter | Fully checked | ||||||
| Axivion Bauhaus Suite | 
 | CertC-ARR01 | Fully implemented | ||||||
| CodeSonar | 
 | LANG.TYPE.SAP | sizeof Array Parameter | 
| Compass/ROSE | 
| Can detect violations of the recommendation | 
| but | 
| cannot distinguish between incomplete array declarations and pointer declarations | |||||||||
| Helix QAC | 
 | C1321 | |||||||
| Klocwork | 
 | CWARN.MEMSET.SIZEOF.PTR | Fully implemented | ||||||
| LDRA tool suite | 
 | 401 S | Fully implemented | ||||||
| Parasoft C/C++test | 
 | CERT_C-ARR01-a | Do not call 'sizeof' on a pointer type | ||||||
| PC-lint Plus | 
 | 682, 882 | Fully supported | ||||||
| Polyspace Bug Finder | 
 | Checks for: 
 Rec, fully covered. | |||||||
| Splint | 
 | ||||||||
| PVS-Studio | 
 | V511, V512, V514, V568, V579, V604, V697, V1086 | |||||||
| RuleChecker | 
 | sizeof-array-parameter | Fully checked | 
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Key here (explains table format and definitions)
| Taxonomy | Taxonomy item | Relationship | 
|---|---|---|
| CERT C | 
...
...
ISO/IEC 9899:1999 Section 6.7.5.2, "Array declarators"
...
...
| Use of sizeof() on a | 
...
Bibliography
...
| pointer type | Prior to 2018-01-12: CERT: | |
| ISO/IEC TS 17961 | Taking the size of a pointer to determine the size of the pointed-to type [sizeofptr] | Prior to 2018-01-12: CERT: Unspecified Relationship | 
| MITRE CWE | CWE-569 | Prior to 2018-01-12: | 
| MITRE CWE | CWE-783 | Prior to 2018-01-12: | 
Bibliography
| [Drepper 2006] | Section | 
...
| 2.1.1, | 
...
| "Respecting | 
...
| Memory | 
...
| Bounds" | |
| [ISO/IEC 9899:2011] | Subclause 6.5.3.4, "The sizeofand_AlignofOperators" | 
...
06. Arrays (ARR) ARR02-C. Explicitly specify array bounds, even if implicitly defined by an initializer