计数排序的奇怪输出C

时间:2014-04-04 06:46:43

标签: c

我有以下计数排序功能

/*
 *File: countingSort.c
 *Description: A counting sort subroutine. Takes as input an array of integers.
 *             an array length and a range. All values in the input array must fall within                  [0, range].
 *            Takes O(range + arrayLen) time and O(range + arrayLen) extra space
 *
*/

#include "countingSort.h"

int* countingSort(int unsorted[], int arrayLen, int range) {
  int store[range + 1];
  int sorted[arrayLen];

  for ( int i = 0; i <= range; i++ ) {
    store[i] = 0;
  }

  for ( int i = 0; i < arrayLen; i++ ) {
    sorted[i] = 0;
  }

  for ( int j = 0; j < arrayLen; j++ ) {
    store[unsorted[j]] ++;
  }

  for ( int i = 1; i <= range; i++ ) {
    store[i] += store[i-1];
  }

  for( int j = arrayLen - 1; j >= 0; j-- ) {
    sorted[store[unsorted[j]]] = unsorted[j];
    store[unsorted[j]] --;
  }

  return sorted;
}

这个功能给了我很奇怪的输出。输出大多数时候都不像输入,但有时它只是起作用。 为什么会这样?

我从另一个名为cSortTest.c的文件中调用它。 该文件看起来像这样

/*
 *File: cSortTest.c
 *Description: Tests countingSort.c
 *
*/

#include <stdio.h>
#include "countingSort.h"

int main() {
  int data[8] = { 2, 1, 9, 4, 4, 56, 90, 3 };
  int* p;

  p = countingSort(data, 8, 90);
  for ( int i = 0; i < 8; i++ ) {
    printf("%d Element: %d\n", i, *(p+i) );
  }
}

1 个答案:

答案 0 :(得分:3)

您正在返回本地数组变量。当函数退出时,此变量将被销毁,从而使其地址不再安全或无效。事实上,访问它将为您提供所谓的未定义行为,这解释了为什么它有时会出现在&#34; work&#34;。

这是C中经典的初学者错误。您必须在所需的目标数组中使用调用者传递,或者使用malloc()来分配&#34; persistent&#34;堆内存并返回:

int* countingSort(int unsorted[], int arrayLen, int range) {
  int *sorted = malloc(arrayLen * sizeof *sorted );
  if (sorted== NULL)
    return NULL;
  /* rest of sorting */
  return sorted;
}

arrayLen * sizeof *sorted表达式计算分配所需的字节数。没有必要使用calloc()来清除记忆;你要覆盖每个元素,所以清除它只是浪费精力。