Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Non-compliant Code Example 1

In this example, a file is opened for reading. If the file is opened successfullyThe following piece of code validates the number of command line arguemnts. If the correct number of commmand line arguements have been specified, memory is allocated by with malloc() and referenced by str. A message indicating that the file was opened properly Next, the second command line argument is copied into the dynamically-allocated memory referenced by str and printed. Afterwards, the memory is deallocted by calling free(). If the file does not open correctly, however str for further processing. Once this processing is complete, str is freed.However, if the incorrect number of arguments have been specified, str is set to a string literal and printed. Because str now references memory that was not dynamically allocated, an error will occur when this str memory is freed.

Code Block
FILE *file = NULL;

int main(int argc, char *str  = NULL, *fname="~/config_file";
size_t size = 100;

file = fopen("~/config_file","r");
if (file != NULLargv[]) {
  char *str = NULL;	
  if (argc == 2) {
    str = (char *)malloc(sizemalloc(strlen(argv[1]));
    if (str == NULL) {  
      /* Handle Allocation Error */
    }
    snprintfstrcpy(str, size, "File %s opened properly", fnameargv[1]);
  printf("LOG: %s\n", str);
}
}
  else {
    str = "ERROR OPENING FILEusage: $>a.exe [string]";
    printf("LOG: %s\n", str);
  }
  /* ... */
  free(str);
  return 0;
}

Compliant Solution 1

In the compliant solution, the call to free() theprogram has been moved inside the conditional statement to ensure that only dynamic memory is freedchanged to eliminate the possibility of str referencing non-dynamic memory and when it is supplied to free().

Code Block
FILE *file = NULL;

int main(int argc, char *str  = NULL, *fname="~/config_file";
size_t size = 100;

file = fopen("~/config_file","r");
if (file != NULL) {
argv[]) {
  char *str = NULL;	
  if (argc == 2) {
    str = (char *)malloc(sizemalloc(strlen(argv[1]));
    if (str == NULL) {  
      /* Handle Allocation Error */
    }
   snprintf strcpy(str, size, "File %s opened properly", fname);
argv[1]);
  }
  else {    
    printf("LOGusage: %s $>a.exe [string]\n", str);
    return free(str)1;
  }
  /* only dynamic memory is freed ... */
}
else {
  str = "ERROR OPENING FILE"free(str);
  printf("LOG: %s\n", str)return 0;
}

Non-compliant Code Example 2

This example attempts to resize the string referenced by buf to make enough room to append the string line. However, once in the function append(), there is no way to determine how buf was allocated. When realloc() is called on buf, since buf does not point to dynamic memory, an error may occur.

Code Block
void append(char *buf, size_t count, size_t size) {
  char *line = " <- THIS IS A LINE";
  int line_len = strlen(line);

  if ((count + line_len) > size) {
    buf = realloc(buf,count+line_len);
    size = count + line_len;
  }
  strncat(buf,line,line_lenstrcat(buf,line);
}

int main(void) {
  append("AAAAA",5,6);
  return 0;
}

Compliant Solution 2

Correcting the above example is an exercise in documentation. Since realloc is used to resize the memory pointed to by buf, the function append has the precondition that buf must point to dynamically allocated memory.

...

h2. Compliant Solution 2

Correcting the above example is an exercise in documentation. Since realloc is used to resize the memory pointed to by buf, the function append has the precondition that buf must point to dynamically allocated memory.

/* NOTE: buf must point to dynamically allocated memory */
void append(char *buf, size_t count, size_t size) {
char *line = " <- THIS IS A LINE";
int line_len = strlen(line);

if ((count + line_len) > size)
buf = realloc(buf,count+line_len);

...


strncat(buf

...

,line

...

);
}

} int main(void) { size_t size = 6, count = 5; char *str = malloc(size); strncpy(str,"AAAAA", size); append(str,size,count); free(str); return 0; }
Code Block

Compliant Code Example 2A

Alternatively, the function append could be rewritten not to use realloc() to resize buf. This solution goes beyond the scope of this document, but is nonetheless viable and, depending on the context of the program, may be preferred.

...