Witam serdecznie. Napisałem program w C, którego kod wklejam poniżej. Program przeprowadza wybory ogłaszając zwycięzców na podstawie kryterium A (kandydat wybrany w najmniejszej ilości sąsiedzkich miast) lub B (największej), a na końcu wypisując koszt ich kampanii mierzony ilością przejętych miast. Język ten jest dla mnie jednak stosunkowo nowy i dopuściłem się jakiś strasznych zbrodni przeciwko pamięci, których kompilator nie chcę mi wybaczyć, a sam nie jestem w stanie znaleźć ich i zadośćuczynić. Podczas sprawdzania warunku if (tempTownListElement->town->takenByA == counter2)
VisualStudio nie widzi wartości wewnętrznych zmiennych, a gcc zwraca wesołe segmentation fault. Gdzie popełniłem błąd?
#include <stdio.h>
#include <stdlib.h>
#define getc_unlocked _fgetc_nolock
typedef struct Town Town;
typedef struct TownList TownList;
typedef struct TownListElement TownListElement;
typedef struct Candidate Candidate;
struct Town
{
int takenByA;
int takenByB;
int futureWinnerA;
int futureWinnerB;
TownList* neighbourTownList;
};
struct TownList
{
TownListElement* firstElement;
int elementCount;
};
struct TownListElement
{
Town* town;
TownListElement* nextTown;
};
void townListAdd(TownList* list, Town* town)
{
if (list == 0){
TownList* newList = malloc(sizeof(*newList));
newList->firstElement = malloc(sizeof(TownListElement));
newList->firstElement->town = town;
newList->firstElement->nextTown = 0;
newList->elementCount = 0;
list = newList;
}
else{
TownListElement* newElement = malloc(sizeof(*newElement));
newElement->town = town;
newElement->nextTown = list->firstElement;
list->firstElement = newElement;
}
list->elementCount++;
}
struct Candidate
{
int costA;
int costB;
};
int main()
{
register int character = getc_unlocked(stdin);
register int number = 0;
register int counter1;
register int counter2;
int townCount;
Town* townsArray;
int tempTownConnection1;
int tempTownConnection2;
int candidateCount;
Candidate* candidateArray;
int takenTownsCount = 0;
int candidateOccurenceA;
int candidateOccurenceB;
int maxOccurence;
int minOccurence;
TownListElement* tempTownListElement;
while (character > 47){
number = (number << 1) + (number << 3) + character - 48;
character = getc_unlocked(stdin);
}
townCount = number;
townsArray = malloc(townCount*sizeof(*townsArray));
for (counter1 = 0; counter1 < townCount; counter1++){
townsArray[counter1].takenByA = -1;
townsArray[counter1].takenByB = -1;
townsArray[counter1].futureWinnerA = -1;
townsArray[counter1].futureWinnerB = -1;
townsArray[counter1].neighbourTownList = 0;
}
while (1){
character = getc_unlocked(stdin);
if (character == '-'){
getc_unlocked(stdin);
getc_unlocked(stdin);
getc_unlocked(stdin);
getc_unlocked(stdin);
getc_unlocked(stdin);
break;
}
number = 0;
while (character > 47){
number = (number << 1) + (number << 3) + character - 48;
character = getc_unlocked(stdin);
}
tempTownConnection1 = number;
character = getc_unlocked(stdin);
number = 0;
while (character > 47){
number = (number << 1) + (number << 3) + character - 48;
character = getc_unlocked(stdin);
}
tempTownConnection2 = number;
townListAdd(&townsArray[tempTownConnection1].neighbourTownList, &townsArray[tempTownConnection2]);
townListAdd(&townsArray[tempTownConnection2].neighbourTownList, &townsArray[tempTownConnection1]);
}
character = getc_unlocked(stdin);
number = 0;
while (character > 47){
number = (number << 1) + (number << 3) + character - 48;
character = getc_unlocked(stdin);
}
candidateCount = number;
candidateArray = malloc(candidateCount*sizeof(*candidateArray));
for (counter1 = 0; counter1 < candidateCount; counter1++){
character = getc_unlocked(stdin);
number = 0;
while (character > 47){
number = (number << 1) + (number << 3) + character - 48;
character = getc_unlocked(stdin);
}
townsArray[number].takenByA = counter1;
townsArray[number].takenByB = counter1;
candidateArray[counter1].costA=1;
candidateArray[counter1].costB=1;
takenTownsCount++;
}
while (takenTownsCount != townCount){
for (counter1 = 0; counter1 < townCount; counter1++){
minOccurence = 10000000;
maxOccurence = 0;
for (counter2 = 0; counter2 < candidateCount; counter2++){
tempTownListElement = townsArray[counter1].neighbourTownList->firstElement;
candidateOccurenceA = 0;
candidateOccurenceB = 0;
while (tempTownListElement){
if (tempTownListElement->town->takenByA == counter2){
candidateOccurenceA++;
}
if (tempTownListElement->town->takenByB == counter2){
candidateOccurenceB++;
}
tempTownListElement = tempTownListElement->nextTown;
}
if (candidateOccurenceA <= minOccurence){
minOccurence = candidateOccurenceA;
townsArray[counter1].futureWinnerA = counter2;
}
if (candidateOccurenceB >= maxOccurence){
if (candidateOccurenceB != maxOccurence){
townsArray[counter1].futureWinnerB = counter2;
}
maxOccurence = candidateOccurenceB;
}
}
}
for (counter1 = 0; counter1 < townCount; counter1++){
townsArray[counter1].takenByA = townsArray[counter1].futureWinnerA;
if (townsArray[counter1].takenByA != -1){
candidateArray[townsArray[counter1].takenByA].costA = townsArray[counter1].takenByA;
}
townsArray[counter1].takenByB = townsArray[counter1].futureWinnerB;
if (townsArray[counter1].takenByB != -1){
candidateArray[townsArray[counter1].takenByB].costB = townsArray[counter1].takenByB;
takenTownsCount++;
}
}
}
for (counter1 = 0; counter1 < candidateCount; counter1++){
printf("%d %d\n", candidateArray[counter1].costA, candidateArray[counter1].costB);
}
}