#include <stdio.h> #include <stdlib.h> #include <string.h> #define swap(type, x, y) \ do \ { \ type t; \ t = x; \ x = y; \ y = t; \ } while (0) /*--- 会員データ ---*/ typedef struct { int no; /* 番号 */ char name[20]; /* 氏名 */ } Member; /*--- 会員の番号の昇順比較関数 ---*/ int AscendingMemberNoCmp(const Member *x, const Member *y) { return x->no < y->no ? -1 : x->no > y->no ? 1 : 0; } /*--- 会員の番号の降順比較関数 ---*/ int DescendingMemberNoCmp(const Member *x, const Member *y) { return x->no < y->no ? 1 : x->no > y->no ? -1 : 0; } /*--- 会員の氏名の昇順比較関数 ---*/ int AscendingMemberNameCmp(const Member *x, const Member *y) { return strcmp(x->name, y->name); } /*--- 会員の氏名の降順比較関数 ---*/ int DescendingMemberNameCmp(const Member *x, const Member *y) { return strcmp(y->name, x->name); } /*--- 会員データ(番号と氏名)の表示(改行あり)---*/ void PrintLnMember(const Member *x) { printf("%d %s\n", x->no, x->name); } /*--- 全データの表示 ---*/ void Print(const Member *data, int *m, int n) { // Print(data, sortindex, ndata); int i; for (i = 0; i < n; i++) PrintLnMember(data + i); } void Number_compare(Member *a, int *m, int n, int compare(const Member *y, const Member *z)) { //heapsort(data, sortindex, ndata, AscendingMemberNoCmp int i; int max = 9; //max == 9; for (i = 0; i <= max; i++) m[i] = 0; /*度数分布表作成*/ //ok for (i = 0; i < n; i++) m[a[i].no]++; /*累積分布表作成*/ //ok for (i = 1; i <= max; i++) { m[i] += m[i - 1]; } /*目的配列の作成*/ Member *b = calloc(n + 1, sizeof(Member)); for (i = n - 1; i >= 0; i--) b[--m[(a[i].no)]] = a[i]; /*配列のコピー*/ for (i = 0; i < n; i++) a[i] = b[i]; if (compare == DescendingMemberNoCmp) { for (i = 0; i < (n / 2); i++) swap(Member, a[n - i - 1], a[i]); } /*解放*/ free(b); b = NULL; } void Name_compare(Member *a, int *m, int n, int compare(const Member *y, const Member *z)) { //heapsort(data, sortindex, ndata, AscendingMemberNoCmp int i; int max = 118; //uの10進数 Member *b = calloc(max, sizeof(Member)); int *s = calloc(max, sizeof(*m) + 1); for (i = 0; i <= max; i++) s[i] = 0; /*度数分布表作成*/ //ok for (i = 0; i < n; i++) s[*(a[i].name)]++; /*累積分布表作成*/ for (i = 1; i <= max; i++) s[i] += s[i - 1]; for (i = n - 1; i >= 0; i--) b[--s[*(a[i].name)]] = a[i]; /*配列のコピー*/ for (i = 0; i < n; i++) { a[i] = b[i]; } /*降順の場合、昇順で並べた配列を逆順にする*/ if (compare == DescendingMemberNameCmp) { for (i = 0; i < (n / 2); i++) swap(Member, a[n - i - 1], a[i]); } /*解放*/ free(b); free(s); b = NULL; s = NULL; } /*--- ヒープソート ---*/ void heapsort(Member *a, int *m, int n, int compare(const Member *y, const Member *z)) { // heapsort(data, sortindex, ndata, AscendingMemberNoCmp); //ndata == 8 if (compare == AscendingMemberNoCmp) Number_compare(a, m, n, AscendingMemberNoCmp); if (compare == DescendingMemberNoCmp) Number_compare(a, m, n, DescendingMemberNoCmp); if (compare == AscendingMemberNameCmp) Name_compare(a, m, n, AscendingMemberNameCmp); if (compare == DescendingMemberNameCmp) Name_compare(a, m, n, DescendingMemberNameCmp); } /*--- メニュー ---*/ typedef enum { TERMINATE, ASCEND_NO, ASCEND_NAME, DESCEND_NO, DESCEND_NAME, PRINT_ALL } Menu; /*--- メニュー選択 ---*/ Menu SelectMenu(void) { int i, ch; char *mstring[] = { "番号で昇順ソート", "名前で昇順ソート", "番号で降順ソート", "名前で降順ソート", "データを表示"}; do { for (i = TERMINATE; i < PRINT_ALL; i++) { printf("(%2d) %-22.22s ", i + 1, mstring[i]); if ((i % 3) == 2) putchar('\n'); } printf("( 0) 終了 :"); scanf("%d", &ch); } while (ch < TERMINATE || ch > PRINT_ALL); return (Menu)ch; } /*--- メイン ---*/ int main(void) { Menu menu; Member data[] = { {1, "takahashi"}, {3, "konishi"}, {5, "ueda"}, {7, "sato"}, {9, "niimi"}, {8, "okonishi"}, {2, "motoike"}, {4, "agemi"}}; int ndata = sizeof(data) / sizeof(data[0]); int i, *sortindex = calloc(ndata, sizeof(int)); for (i = 0; i < ndata; i++) sortindex[i] = i; /* data[]の添字を管理する配列*/ do { switch (menu = SelectMenu()) { case ASCEND_NO: /* 番号で昇順にソート */ heapsort(data, sortindex, ndata, AscendingMemberNoCmp); break; case ASCEND_NAME: /* 名前で昇順にソート */ heapsort(data, sortindex, ndata, AscendingMemberNameCmp); break; case DESCEND_NO: /* 番号で降順にソート */ heapsort(data, sortindex, ndata, DescendingMemberNoCmp); break; case DESCEND_NAME: /* 名前で降順にソート */ heapsort(data, sortindex, ndata, DescendingMemberNameCmp); break; case PRINT_ALL: /* 全データを表示 */ Print(data, sortindex, ndata); break; } } while (menu != TERMINATE); free(sortindex); sortindex = NULL; return 0; }
Name_compare関数の int *s = calloc(max, sizeof(*m) + 1);
についての質問です。
<質問>
int *s = calloc(max, sizeof(*m) + 1);の場合は、うまく機能するのですが
int *s = calloc(max, sizeof(m));の場合は、プログラムが強制終了してしまいます。
なぜなのか、原因をご教授お願いします。
ちなみに、sはsortindexだと領域が足りないため、増やそうと思いsというのを宣言しました。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/22 06:39
2020/07/22 06:40
2020/07/22 06:43