2016-11-13 3 views
-1

ポインタを使用して構造体をソートしようとすると、セグメンテーションフォールトエラーが発生します。私はそれが実行されたときに "デバッグMSG 2"が印刷されていないので、 'main()'の 'scanf_s'関数に問題があると思います。ここに完全なコードがあります。C:関数ポインタのセグメンテーションフォルト

#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); 
    } 
} 
+3

あなたは[___MCVE___](http://stackoverflow.com/help/mcve)の作成を気にしますか? –

+1

'scanf_s("%s "にはバッファサイズのパラメータが必要です。[scanf_s](https://msdn.microsoft.com/en-us/library/w40768et.aspx) – BLUEPIXY

答えて

1

あなたは、人々のテーブルをmallocingしているすべての権利

それdoesnの(あなたがmallocのリターンをキャストする必要はありませんが、それは詳細だことを除いて)

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

nameメンバ構造のメモリを割り当てます。

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

また、BLUEPIXYが気づいたように、(私はそれが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の配列を割り当てるだけで十分です。

+2

' scanf_s( "%50s%f%d "、人[i] .name、' - > 'scanf_s("%49s%f%d "、people [i] .name、50、' – BLUEPIXY

+0

は固定されています(とにかく主な問題ではない) –

+1

'% [scanf_s](https://msdn.microsoft.com/en-us/library/w40768et.aspx)また、 'char name [49];' - > – BLUEPIXY