C:函数指针的分段错误

时间:2016-11-13 16:04:30

标签: c pointers segmentation-fault

尝试使用指针对结构进行排序时出现分段错误错误。我想它会在'main()'中的'scanf_s'函数中出现问题,因为执行时不会打印“Debug MSG 2”。这是完整的代码。

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct contestant
{
    char *name;
    float height;
    int weight;
} ppl;

typedef int(*Funcptr)(ppl *, ppl *);

int namecmp(ppl *, ppl *);
int heightcmp(ppl *, ppl *);
int weightcmp(ppl *, ppl *);
void sort(Funcptr, Funcptr, Funcptr, ppl *, int);

int main()
{
    int i;
    int num;
    ppl *people;

    scanf_s("%d", &num);

    people = (ppl *)malloc(num * sizeof(ppl));

    printf("Debug MSG 1\n");

    for (i = 0; i<num; i++)
        scanf_s("%s %f %d", people[i].name, &(people[i].height), &(people[i].weight));

    printf("Debug MSG 2\n");

    sort(namecmp, heightcmp, weightcmp, people, num);
    sort(heightcmp, weightcmp, namecmp, people, num);
    sort(weightcmp, namecmp, heightcmp, people, num);

    free(people);
}

int namecmp(ppl *human1, ppl *human2)
{
    char *temp;

    if (strcmp(human1->name, human2->name) > 0)
    {
        temp = human1->name;
        human1->name = human2->name;
        human1->name = temp;
        return 1;
    }

    else if (strcmp(human1->name, human2->name) == 0)
        return 0;

    else
        return -1;
}

int heightcmp(ppl *human1, ppl *human2)
{
    float temp;

    if (human1->height > human2->height)
    {
        temp = human1->height;
        human1->height = human2->height;
        human2->height = temp;
        return 1;
    }

    else if (human1->height == human2->height)
        return 0;

    else
        return -1;
}

int weightcmp(ppl *human1, ppl *human2)
{
    int temp;

    if (human1->weight > human2->weight)
    {
        temp = human1->weight;
        human1->weight = human2->weight;
        human2->weight = temp;
        return 1;
    }

    else if (human1->weight > human2->weight)
        return 0;

    else
        return -1;
}

void sort(Funcptr func1, Funcptr func2, Funcptr func3, ppl *person, int number)
{
    int i, j;
    int res1, res2;

    for (i = 0; i<number - 1; i++)
    {
        for (j = i + 1; j<number; j++)
        {
            res1 = func1((person + i), (person + j));

            if (res1 == 0)
            {
                res2 = func2((person + i), (person + j));

                if (res2 == 0)
                {
                    func3((person + i), (person + j));
                }
            }
        }
    }

    for (i = 0; i<number; i++)
    {
        printf("%s %.1f %d\n", (person + i)->name, (person + i)->height, (person + i)->weight);
    }
}

1 个答案:

答案 0 :(得分:1)

你正好把人们的桌子搞好了

people = (ppl *)malloc(num * sizeof(ppl));

(除了您不必转换malloc的回复,但这是一个细节)

但这并不能免除为name成员结构分配内存

for (i = 0; i<num; i++)
    scanf_s("%s %f %d", people[i].name, ...

另外,当BLUEPIXY注意到你没有正确使用scanf_s时(我认为它是scanf),你需要传递最大数量的字符,或者只需使用scanf大小限制。

例如修复它:

for (i = 0; i<num; i++)
{
    people[i].name = malloc(51);
    scanf("%50s %f %d", people[i].name, ....
}

替代解决方案:按如下方式定义您的结构:

typedef struct contestant
{
    char name[50];
    float height;
    int weight;
} ppl;

所以不需要malloc这个名字。像你一样分配ppl数组就足够了。