繁体   English   中英

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

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

现在我正在尝试检查我制作的每个 function。 我已经检查完投票和记录偏好 function。 它奏效了。 现在,我对 function 排序感到震惊,我尝试使用归并排序。 在我过去的问题中,我一直在使用这个合并 function,但是,当我这次尝试使用它时。 它向我展示了“分段错误”。 这是我的终端[图 1] ,当我尝试像这张图[图 2]插入选票时。 如您所见,“排序前”出现了,但“排序后”没有出现。 反而出现了“分段错误”。

附言。 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

我的代码 [合并 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);
    }
}

您的代码在第 227 行创建了一个负索引。以下是错误消息。 请使用此链接进行调试。 只需单击“开始”即可构建代码并打开终端。

 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