简体   繁体   English

合并排序 function 中的分段错误:CS50 pset 3; 潮人

[英]Segmentation fault in merge sort function : CS50 pset 3 ; tideman

Now I am in a process that tries to check each function which I have made.现在我正在尝试检查我制作的每个 function。 I have finished checking the vote and record_preference function.我已经检查完投票和记录偏好 function。 It's worked.它奏效了。 Now, I'm struck with the sort function which I try to use merge sort.现在,我对 function 排序感到震惊,我尝试使用归并排序。 I have been using this merge function in my past problem, but, when I try to use it for this time.在我过去的问题中,我一直在使用这个合并 function,但是,当我这次尝试使用它时。 It showed me "segmentation fault".它向我展示了“分段错误”。 Here's my terminal [picture 1] when I try to insert ballots like this picture [picture 2] .这是我的终端[图 1] ,当我尝试像这张图[图 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). score_winner 是一个变量,我使用它就像分数标签一样按升序对对进行排序。我认为终端应该看起来像(下图)。

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.]我的代码 [合并 function 在最里面。]

#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.您的代码在第 227 行创建了一个负索引。以下是错误消息。 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]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM