Versions Compared

Key

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

...

The problem arises in this setup when no items are being stocked. getStock would recognize that length = 0 and thus would return NULL. In this noncompliant code example, erroneous behavior results from getStock returning NULL while main neglects to check for such a value. This results in an abnormal program termination after returning to the main function.

Code Block
bgColor#FFCCCC
langc
#include <stdio.h>
enum { INV_SIZE=20 };

typedef struct {
  size_t stockOfItem[INV_SIZE];
  size_t length;
} Inventory;

size_t *getStock(Inventory iv);

int main(void) {
  Inventory iv;
  size_t *item;

  iv.length = 0;

  /* Other code that might modify the inventory but still leave no items in it upon completion */

  item = getStock(iv);

  printf("Stock of first item in inventory: %d\n", item[0]);
  
  return 0;
}

size_t *getStock(Inventory iv) {
  if (iv.length == 0) {
    return NULL;
  }
  else {
    return iv.stockOfItem;
  }
}

...

This compliant solution eliminates the NULL return and simply returns the item array, even if it is zero-length. The main function can effectively handle this situation without exhibiting erroneous behavior.

Code Block
bgColor#ccccff
langc
#include <stdio.h>

enum { INV_SIZE=20 };

typedef struct {
  size_t stockOfItem[INV_SIZE];
  size_t length;
} Inventory;

size_t *getStock(Inventory iv);

int main(void) {
  Inventory iv;
  size_t i;
  size_t *item;

  iv.length = 0;
  
  /* Other code that might modify the inventory but still leave no items in it upon completion */
  
  item = getStock(iv);

  if (iv.length != 0) {
    printf("Stock of first item in inventory: %d\n", item[0]);
  }
  
  return 0;
}

size_t *getStock(Inventory iv) {
  return iv.stockOfItem;
}

...

The example below attempts to return an array of the items in stock, sorted by the amount of each item in stock. The arraySort function incorrectly returns NULL instead of a pointer to an empty array when no items are in stock. This will be improperly handled by the main function, which is attempting to print out the returned array. This will result in an abnormal program termination.

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

enum { FINAL_ITEM=SIZE_MAX, INV_SIZE=20 };

size_t *arraySort(size_t *array);

int main(void) {
  size_t i;
  size_t stockOfItem[INV_SIZE];
  size_t *sortedArray;

  /* Other code that might use stockarray but leaves it empty */

  sortedArray = arraySort(stockOfItem);
  
  for (i = 0; sortedArray[i] != FINAL_ITEM; i++) {
	printf("Item stock: %d", sortedArray[i]);
  }
  
  return 0;
}

/* Create new sorted array */
size_t *arraySort(size_t *array) {
  size_t i;
  size_t *sortedArray

  for(i = 0; array[i] != FINAL_ITEM; i++);
  
  if (i == 0) {
    return NULL;
  }

  sortedArray = (size_t*) malloc(sizeof(size_t)*i);
  if (sortedArray == NULL) {
    /* Handle memory error */
  }

  /* Add sorted data to array*/
}

...

The example below correctly returns an empty array in the sortedArray function. If the size of the array is zero, then sortedArray allocates an array of size 1 and fills it with the sentinel value. It can then successfully return that array to the caller function.

Code Block
bgColor#ccccff
langc
#include <stdio.h>

enum { FINAL_ITEM=SIZE_MAX, INV_SIZE=20 };

size_t *arraySort(size_t *array);

int main(void) {
  size_t i;
  size_t stockOfItem[INV_SIZE];
  size_t *sortedArray;


  /* Other code that might use stockarray but leaves it empty */

  sortedArray = arraySort(stockOfItem);
  
  for (i = 0; sortedArray[i] != FINAL_ITEM; i++) {
    printf("Item stock: %d", sortedArray[i]);
  }
  
  return 0;
}

/* Create new sorted array */
size_t *arraySort(size_t *array) {
  size_t i;
  size_t *sortedArray

  for(i = 0; array[i] != FINAL_ITEM; i++);

  if (i == 0) {
    static emptyArray = (size_t*) malloc(sizeof(size_t));
    if(emptyArray == NULL) {
      /* Handle memory error */
    }
    emptyArray[0] = FINAL_ITEM;
    return emptyArray;
  }
  
  sortedArray = (size_t*) malloc(sizeof(size_t)*i);
  if (sortedArray == NULL) {
    /* Handle memory error */
  }

  /* Add sorted data to array*/
}

...