Reputation: 1342
I'm tying to implement Kriskal's algorithm in C++ but...
Unhandled exception at 0x0127160d in DAA.exe: 0xC0000005: Access violation reading location 0xdd2021d4.
It stop on this line in getRoot function:
while(cities[root].prev != NO_PARENT)
I think that the problem is with data in cities array. When I prinf all data in array it's not what I want to be. The names of cities are like this "════════════════¤¤¤¤ллллллллю■ю■" and numbers (int) - like this (-842150451). Below is full code.
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define NO_PARENT -1
struct city {
char name[11];
int prev;
};
struct path {
unsigned i, j, price;
};
bool comparsion(path p1, path p2) {
return p1.price > p2.price;
}
int getRoot(city *cities, int cityNumber) {
int root = cityNumber, tmp;
while(cities[root].prev != NO_PARENT)
root = cities[root].prev;
while(cityNumber != root) {
tmp = cityNumber;
cityNumber = cities[cityNumber].prev;
cities[tmp].prev = root;
}
return root;
}
bool isListed(city *cities, int n, char cityName[]) {
for(int i = 0; i < n; i++)
if(strcmp(cities[i].name, cityName))
return true;
return false;
}
int getCityNumber(city *cities, int n, char cityName[]) {
for(int i = 0; i < n; i++)
if(strcmp(cities[i].name, cityName))
return i;
return NO_PARENT;
}
int minPrice(city *cities, path *paths, int cityCount, int pathCount) {
unsigned minPrice = 0;
// sort paths by price
std::sort(paths, &paths[pathCount-1], comparsion);
for(int k = 0; k < pathCount; k++) {
printf("path: %d - %d\n", paths[k].i, paths[k].j);
int c1 = getRoot(cities, paths[k].i), c2 = getRoot(cities, paths[k].j);
if(c1 != c2) {
minPrice += paths[k].price;
cities[c2].prev = c1;
}
}
return minPrice;
}
int main() {
int n, m, k;
do {
scanf("%d %d %d", &n, &m, &k);
} while(n < 2 || n > 10001 || m < -1 || m > 100001 || k < -1 || k > 100001);
city* cities = (city*)malloc(n*sizeof(city));
path* paths = (path*)malloc((m + k)*sizeof(path));
int addCities = 0;
char city1[11], city2[11];
for(int i = 0; i < (m + k); i++) {
scanf("%s %s", city1, city2);
if(addCities < n && !isListed(cities, n, city1)) { // if city1 is not into cities
// add it
strcpy(cities[addCities].name, city1);
cities[addCities].prev = NO_PARENT;
addCities++;
}
paths[i].i = getCityNumber(cities, n, city1); // number of city1
if(addCities < n && !isListed(cities, n, city2)) { // if city2 is not into cities
// add it
strcpy(cities[addCities].name, city2);
cities[addCities].prev = NO_PARENT;
addCities++;
}
paths[i].j = getCityNumber(cities, n, city1); // number of city2
if(i >= m)
scanf("%d", &paths[i].price);
}
for(int i = 0; i < (m + k); i++)
printf("%s: %d\n", cities[i].name, cities[i].prev);
// Calculate min price
printf("%d ", minPrice(cities, paths, n, k + m));
system("pause");
return 0;
}
Upvotes: 1
Views: 2042
Reputation: 156
you have to initialize the "cities". There are (m+k) paths between n cities but this doesn't necessarily means that all n cities are included in these paths, since you have set the prev member of a city to NO_PARENT
whenever it's listed as city1 or city2, when a city is never listed as those its prev member would be undefined and when you use it as an index in getRoot function while(cities[root].prev != NO_PARENT)
root = cities[root].prev;
this would cause the problem.
Upvotes: 1
Reputation: 431
In isListed() and getCityNumber() you use strcmp() to check string equality. There's two problems with the way you're doing it:
After malloc'ing you need to set cities[i].name to something e.g. "unnamed" or just "\0". Otherwise, strcmp will get called on uninitialised strings - and if they don't contain a null character within 11 chars, it will fail. Add this code after the malloc lines:
for( int i = 0 ; i < n ; ++ i ) {
cities[ i ].name[ 0 ] = '\0';
cities[ i ].parent = NO_PARENT;
}
Upvotes: 1