Now I am in a process that tries to check each function which I have made. I have finished checking the vote and record_preference function. It's worked. Now, I'm struck with the sort function which I try to use merge sort. I have been using this merge function in my past problem, but, when I try to use it for this time. It showed me "segmentation fault". Here's my terminal [picture 1] when I try to insert ballots like this picture [picture 2] . As you see, "Before sort" has appeared but "After sort" hasn't. "Segmentation fault" has appeared instead.
ps. score_winner is a variable that I made for using it like score tags for sorting pairs in increasing order.What on my mind is the terminal should appear like (below).
before sort :
pair 0 :7 alice bob
pair 1 :6 charlie alice
pair 2 :5 bob charlie
after sort :
pair 0 :5 bob charlie
pair 1 :6 charlie alice
pair 2 :7 alice bob
My code [the merge function is inmost.]
#include <cs50.h>
#include <stdio.h>
#include <string.h>
// Max number of candidates
#define MAX 9
// preferences[i][j] is number of voters who prefer i over j
int preferences[MAX][MAX];
// locked[i][j] means i is locked in over j
bool locked[MAX][MAX];
// Each pair has a winner, loser
typedef struct
{
int winner;
int loser;
}
pair;
// Array of candidates
string candidates[MAX];
pair pairs[MAX * (MAX - 1) / 2];
int pair_count;
int candidate_count;
// Function prototypes
void merge(int left, int mid, int right);
void merge_sort(int left, int right);
bool vote(int rank, string name, int ranks[]);
void record_preferences(int ranks[]);
void add_pairs(void);
void sort_pairs(void);
int main(int argc, string argv[])
{
// Check for invalid usage
if (argc < 2)
{
printf("Usage: tideman [candidate ...]\n");
return 1;
}
// Populate array of candidates
candidate_count = argc - 1;
if (candidate_count > MAX)
{
printf("Maximum number of candidates is %i\n", MAX);
return 2;
}
for (int i = 0; i < candidate_count; i++)
{
candidates[i] = argv[i + 1];
}
// Clear graph of locked in pairs
for (int i = 0; i < candidate_count; i++)
{
for (int j = 0; j < candidate_count; j++)
{
locked[i][j] = false;
}
}
pair_count = 0;
int voter_count = get_int("Number of voters: ");
// Query for votes
for (int i = 0; i < voter_count; i++)
{
// ranks[i] is voter's ith preference
int ranks[candidate_count];
// Query for each rank
for (int j = 0; j < candidate_count; j++)
{
string name = get_string("Rank %i: ", j + 1);
if (!vote(j, name, ranks))
{
printf("Invalid vote.\n");
return 3;
}
}
record_preferences(ranks);
printf("\n");
}
add_pairs();
printf("%i \n", pair_count);
printf("before sort : \n");
for(int i=0;i<pair_count;i++)
{
printf("pair %i :", i);
printf("%i ", preferences[pairs[i].winner][pairs[i].loser]); //score of winner
printf("%s ", candidates[pairs[i].winner]);
printf("%s ", candidates[pairs[i].loser]);
printf("\n");
}
printf("\n");
merge_sort(0, pair_count - 1);
printf("after sort : ");
for(int i=0;i<pair_count;i++)
{
printf("pair %i :", i);
printf("%i ", preferences[pairs[i].winner][pairs[i].loser]); //score of winner
printf("%s ", candidates[pairs[i].winner]);
printf("%s ", candidates[pairs[i].loser]);
printf("\n");
}
printf("\n");
return 0;
}
// Update ranks given a new vote
bool vote(int rank, string name, int ranks[])
{
// TODO
string name1[candidate_count];
for (int i = 0; i < candidate_count; i++)
{
name1[i] = candidates[i];
}
int sum = 0;
for (int j = 0; j < candidate_count; j++)
{
if (strcmp(name, name1[j]) == 0)
{
sum = sum + 1;
ranks[rank] = j;
}
else
{
sum = sum + 0;
}
}
if (sum == 1)
{
return true;
}
else
{
return false;
}
}
// Update preferences given one voter's ranks
void record_preferences(int ranks[])
{
// TODO
for (int i = 0; i < candidate_count; i++)
{
for (int j = 0; j < candidate_count; j++)
{
if (i < j)
{
preferences[ranks[i]][ranks[j]] = preferences[ranks[i]][ranks[j]] + 1;
}
else
{
preferences[ranks[i]][ranks[j]] = preferences[ranks[i]][ranks[j]] + 0;
}
}
}
return;
}
// Record pairs of candidates where one is preferred over the other
void add_pairs(void)
{
// TODO
for (int i = 0; i < candidate_count; i++)
{
for (int j = 0; j < candidate_count; j++)
{
if (i < j)
{
if (preferences[i][j] < preferences[j][i])
{
pairs[pair_count].winner = j;
pairs[pair_count].loser = i;
pair_count = pair_count + 1;
}
else if (preferences[i][j] > preferences[j][i])
{
pairs[pair_count].winner = i;
pairs[pair_count].loser = j;
pair_count = pair_count + 1;
}
else
{
pair_count = pair_count + 0;
}
}
}
}
return;
}
// Sort pairs in decreasing order by strength of victory
void sort_pairs(void)
{
// TODO
merge_sort(0, pair_count - 1);
}
void merge(int left, int mid, int right)
{
int len1 = mid - left + 1;
int len2 = right - mid;
int i;
int index1 = 0, index2 = 0;
// create temp array
int score_winner[MAX];
for (i = 0; i < pair_count; i++)
{
score_winner[i] = preferences[pairs[i].winner][pairs[i].loser];
}
int left_array[len1];
int right_array[len2];
int str_win_left_array[len1];
int str_win_right_array[len2];
int str_los_left_array[len1];
int str_los_right_array[len2];
//take array to temp array
for (i = 0; i < len1; i++)
{
left_array[i] = score_winner[left + i];
str_win_left_array[i] = pairs[left + i].winner;
str_los_left_array[i] = pairs[left + i].loser;
}
for (i = 0; i < len2; i++)
{
right_array[i] = score_winner[mid + 1 + i];
str_win_left_array[i] = pairs[mid + 1 + i].winner;
str_los_left_array[i] = pairs[mid + 1 + i].loser;
}
i = left;
while (index1 < len1 && index2 < len2)
{
if (left_array[index1] < right_array[index2])
{
score_winner[i] = left_array[index1];
pairs[i].winner = str_win_left_array[index1];
pairs[i].loser = str_los_left_array[index1];
index1++;
}
else
{
score_winner[i] = right_array[index2];
pairs[i].winner = str_win_right_array[index2];
pairs[i].loser = str_los_right_array[index2];
index2++;
}
i++;
}
// check for other one
while (index1 < len1)
{
score_winner[i] = left_array[index1];
pairs[i].winner = str_win_left_array[index1];
pairs[i].loser = str_los_left_array[index1];
i++;
index1++;
}
while (index2 < len2)
{
score_winner[i] = right_array[index2];
pairs[i].winner = str_win_right_array[index2];
pairs[i].loser = str_los_right_array[index2];
i++;
index2++;
}
}
void merge_sort(int left, int right)
{
int mid;
int i;
if (left < right)
{
mid = (left + right) / 2;
merge_sort(left, mid);
merge_sort(mid + 1, right);
merge(left, mid, right);
}
}
Your code created a negative index at line 227. The following is the error message. Please use this link to debug it. Just click "Start" to build the code and bring up the terminal.
Memory access error: reading from the outside of a memory space; abort execution.
# Reading 4 bytes from 0xf7a36fc0 will read undefined values.
#
# The memory-space-to-be-read (start:0x824c960, size:324 bytes) is bound to 'preferences' at
# file:/prog.c::9, 0
#
# 0x824c960 0x824caa3
# +------------------------------+
# ......| the memory-space-to-be-read |
# +------------------------------+
# ^~~~~~~~~~
# the read starts at 0xf7a36fc0 that is 276912544 bytes before the memory-space start.
#
# Stack trace (most recent call first) of the read.
# [0] file:/prog.c::227, 9
# [1] file:/prog.c::299, 9
# [2] file:/prog.c::107, 5
# [3] [libc-start-main]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.