【问题标题】:Error in Sorting Algorithm in C (variation of Radix Sort)C中的排序算法错误(基数排序的变体)
【发布时间】:2014-11-02 13:22:04
【问题描述】:

我正在学习 C,我在互联网上阅读了一些排序算法。 我尝试制作自己的排序算法,它看起来有点像基数排序。 Radix sort on Wikipedia。下面是一个带有我的排序算法的程序。

#include <stdio.h>
#include <stdlib.h>

/* prints all elements of an array of n length */
void printArray(int *arr, int n){
  if (n < 0){
    return;
  } else if (n == 0){
    printf("()\n");
  } else {
    int i;
    printf("(%d", arr[0]);
    for(i=1; i<n; i++){
      printf(", %d", arr[i]);
    }
    printf(")\n");
  }
}

/* safe replacement for malloc. */
void *safeMalloc(int size) {
  void *ptr = malloc(size);
  if (ptr == NULL) {
    printf("\nError: memory allocation failed....abort\n");
    printf("\nNot enough space for %d int numbers\n", size);
    exit(-1);
  }
  return ptr;
}

/* safe replacement for realloc. */
int *resizeArray(int *arr, int newSize){
  int *ptr = realloc(arr, newSize*sizeof(int));
  if (ptr == NULL) {
    printf("\nError: memory allocation failed....abort\n");
    exit(-1);
  }
  return ptr;
}

/* check if array is sorted */
void checkArray(int length, int *a){
  int i;
  for(i=0; i<length-i; i++){
    if (a[i] > a[i+1]){
      printArray(a, length);
      printf("Error in: %d\n", i);
      return;
    }
  }
}

/*///////////////////////////////////////////////////
 * /////////////// SORTING ALGORITHM ////////////////
 * ////////////////////////////////////////////////*/
void sort(int length, int a[], int digits){
  /* base case */
  if ((length <= 1) || (digits == 0)){
    return;
  }
  /* recursive case */
  /* declare variables */
  int i, j, digit, idx = 0, sum = 0;
  int *copy[10], lengthCopy[10];
  for(i=0; i<10; i++){
    lengthCopy[i] = 0;
    copy[i] = safeMalloc(sizeof(int));
  }
  for(i=0; i<length; i++){
    /* get the n'th digit. Example: a[i]=12345 and digits=100 --> digit=3 */  
    digit = (a[i]/digits)%10;

    lengthCopy[digit]++;
    if (lengthCopy[digit] > 1){
      resizeArray(copy[digit], lengthCopy[digit]);
    }
    copy[digit][lengthCopy[digit]-1] = i;
  }
  /* Get the values */
  for(i=0; i<10; i++){
    for(j=0; j<lengthCopy[i]; j++){
      copy[i][j] = a[copy[i][j]];
    }
  }
  /* fill in the elements of copy in the original array */
  for(i=0; i<10; i++){
    for(j=0; j<lengthCopy[i]; j++){
      a[idx] = copy[i][j];
      idx++;
    }
    /* copy[i] is no longer necessary, so free it */
    free(copy[i]);
  }

  for(i=0; i<10; i++){
    /* call recursive function */
    sort(lengthCopy[i], &a[sum], digits/10);
    sum += lengthCopy[i];
  }
}

int getMax(int length, int a[]){
  int i, max = 1;
  for(i=0; i<length; i++){
    while(a[i] > max*10){
      max *= 10;
    }
  }
  return max;
}

int main(int argc, char *argv[]){
  int i, *a, length=20;
  a = safeMalloc(length*sizeof(int));
  for(i=0; i<length; i++){
    a[i] = rand()%100;
  }
  sort(length, a, getMax(length, a));
  checkArray(length, a);
  printArray(a, length);
  free(a);
  return 0;
}

现在,当我尝试我的程序时,非常奇怪的是,当我在主函数中出现分段错误时:int length = 1000,但如果我输入了:int length = 20;

我不知道这个错误来自哪里。有人可以帮我吗?

提前致谢,

帕特里克

附言对不起我的英语,这不是我的第一语言;)

【问题讨论】:

  • 我打赌你在某个地方出界了。
  • 要知道错误来自哪里,请使用标志-g 编译您的代码,如gcc -g ...。然后,使用 valgrind 运行您的程序:valgrind ./a.out &lt;params&gt;。这应该会引导您找到问题的根源。祝你好运!

标签: c algorithm sorting segmentation-fault radix-sort


【解决方案1】:

正如 Rubens 所建议的,使用 Valgrind 会直接导致错误:

==7369== Invalid write of size 4
==7369==    at 0x400991: sort (/tmp/t.c:77)
==7369==    by 0x400BF2: main (/tmp/t.c:118)
==7369==  Address 0x4de46e4 is 0 bytes after a block of size 4 free'd
==7369==    at 0x402FD9E: realloc (valgrind/coregrind/m_replacemalloc/vg_replace_malloc.c:661)
==7369==    by 0x4007AA: resizeArray (/tmp/t.c:33)
==7369==    by 0x40096A: sort (/tmp/t.c:75)
==7369==    by 0x400BF2: main (/tmp/t.c:118)

在您realloc 之后,您无法访问旧数组,您必须使用新数组。您的 resizeArray 函数返回新数组是有原因的;忽略该返回值是一个错误。

现在,尽管有这个错误,您的程序仍然“有效”,但只是偶然。堆损坏错误就是这样令人讨厌。

【讨论】:

  • 谢谢,我忘记了我的函数 resizeArray 有一个返回值,但我从未将该值分配给我的旧数组。所以,现在它是固定的:copy[digit] = resizeArray(copy[digit], lengthCopy[digit]);非常感谢!
猜你喜欢
  • 1970-01-01
  • 2012-03-05
  • 1970-01-01
  • 1970-01-01
  • 2016-11-27
  • 2019-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多