2013-08-01 5 views
0

Я пытаюсь найти рудиментарный вид радикса (я его никогда не видел, поэтому я сожалею, если мой ужас), но я получаю EXC_BAD_ACCESS ошибка на линии link = *(link.pointer);. Мои навыки C невелики, поэтому, надеюсь, кто-то может научить меня, что я делаю неправильно.EXC_BAD_ACCESS на указателе в связанном списке для сортировки radix

Я использую XCode и ARC.

Вот код:

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

#define ARRAY_COUNT 10 
#define MAX_VALUE 1000000 
#define MODULO 10.0f 

typedef enum 
{ 
    false, 
    true 
} bool; 

typedef struct linkedListStruct 
{ 
    int value; 
    struct linkedListStruct *pointer; 
} LinkedList; 

void radixSort(int *array); 
bool arraySorted(int *array); 
int * intArray(int minValue, int maxValue); 

int main(int argc, const char * argv[]) 
{ 
    int *sortingArray = intArray(0, MAX_VALUE); 

    radixSort(sortingArray); 

    printf("Array %s sorted", arraySorted(sortingArray) ? "" : "not"); 

    return 0; 
} 

void radixSort(int *array) 
{ 
    int numberOfIterations = (int)ceilf(log(MAX_VALUE)/log(MODULO)); 
    for(int n = 0; n < numberOfIterations; n++) 
    { 
     LinkedList *linkedListPointers[(int)MODULO] = {0}; 
     int i = ARRAY_COUNT; 
     while(i--) 
     { 
      int location = (int)floor((array[i] % (int)powf(MODULO, n + 1))/powf(MODULO, n)); 
      LinkedList link = { array[i], NULL }; 
      link.pointer = linkedListPointers[location]; 
      linkedListPointers[location] = &link; 
     } 
     int location = 0; 
     for(int pointerSelection = 0; pointerSelection < MODULO; pointerSelection++) 
     { 
      if(linkedListPointers[pointerSelection]) 
      { 
       LinkedList link = { 0, linkedListPointers[pointerSelection] }; 
       linkedListPointers[pointerSelection] = NULL; 
       while(link.pointer) 
       { 
        link = *(link.pointer); 
        array[location++] = link.value; 
       } 
      } 
     } 
    } 
} 

bool arraySorted(int *array) 
{ 
    int i = ARRAY_COUNT; 
    while(--i)if(array[i - 1] > array[i])break; 
    return !i; 
} 

int * intArray(int minValue, int maxValue) 
{ 
    int difference = maxValue - minValue; 
    int *array = (int *)malloc(sizeof(int) * ARRAY_COUNT); 
    int i; 
    for(i = 0; i < ARRAY_COUNT; i++) 
    { 
     array[i] = rand()%difference + minValue; 
    } 
    return array; 
} 

Кроме того, если кто-то хочет предложить улучшения моего рода, которые также будут оценены.

+0

ммм почему у вас есть перечисление с BOOL, BOOL уже определенный тип и часть язык так же, как int, short и т. д. –

+0

@claptrap Я не всегда компилировался с 'C99', так что это скорее привычка, чем что-либо. И даже сейчас я использую GNU99. – RileyE

+0

Что касается комментария @ claptrap, вы можете '#include ' получить тип 'bool' (я считаю, что это typedef' _Bool'). – jxh

ответ

0

Проблема связана с тем, как я назначал связанный список. Я изменил

LinkedList link = { array[i], NULL }; 
link.pointer = linkedListPointers[location]; 

к

LinkedList *link = malloc(sizeof(LinkedList)); 
link->value = array[i]; 
link->pointer = linkedListPointers[location]; 

В первом примере, указатель на link остался прежний через каждую итерацию цикла (я не знал, что будет делать это), так что необходимо, чтобы сделать указатель указывает на недавно выделенный фрагмент памяти.

EDIT:

Изменение, который также заставил меня изменить от

while(link.pointer) 
{ 
    link = *(link.pointer); 
    array[location++] = link.value; 
} 

в

while(linkPointer) 
{ 
    link = *linkPointer; 
    array[location++] = link.value; 
    linkPointer = link.pointer; 
} 
+0

необходимо инициализировать 'LinkedList * linkedListPointers [(int) MODULO] = {0};' – BLUEPIXY

+0

@BLUEPIXY Хороший улов. У меня было это в моем коде, но я забыл упомянуть, что я тоже это изменил. Спасибо! – RileyE