16行目
において、ローカル変数 keep を初期化せずにデリファレンスしているため、
変な所にアクセスしてしまい、危険です。
19行目
コード:
while (node->next == NULL){
のループにおいて、最初にこの条件が真であった場合、24行目
によって node の値が NULL となり、19行目に戻った時にNULLをデリファレンスしてしまい危険です。
また、この条件が偽であった場合、prev が初期化されていない状態で26行目
コード:
prev->next = keep->next;
を実行してしまい、危険です。
例えばこんな感じでやるといいと思います。
コード:
void sort_list(void) {
node_t head; /* 未ソートの要素 */
node_t *result = NULL; /* ソート済みの要素 */
head.next = list;
/* 未ソートの要素が無くなるまで繰り返す */
while (head.next != NULL) {
node_t *maxNodeParent = &head; /* 最大値を持つノードの前のノード */
node_t *maxNode;
node_t *cur;
/* 未ソートの要素の中でvalueが最大のものを検索する */
for (cur = &head; cur->next != NULL; cur = cur->next) {
if (maxNodeParent->next->value < cur->next->value) {
/* 最大値の情報を更新する */
maxNodeParent = cur;
}
}
/* valueが最大のノードを未ソートの要素のリストから切り離し、 */
maxNode = maxNodeParent->next;
maxNodeParent->next = maxNode->next;
/* ソート済みの要素の先頭に接続する */
maxNode->next = result;
result = maxNode;
}
/* ソート結果を書き戻す */
list = result;
}
動作確認用
コード:
void print_list(void) {
node_t* cur = list;
if (cur == NULL) return;
for (;;) {
printf("%d", cur->value);
if (cur->next == NULL) {
putchar('\n');
return;
}
putchar(' ');
cur = cur->next;
}
}
int main(void) {
node_t nodes[N];
int i;
for (i = 0; i < N; i++) {
if (scanf("%d", &nodes[i].value) != 1) return 1;
nodes[i].next = i + 1 < N ? &nodes[i + 1] : NULL;
}
list = &nodes[0];
print_list();
sort_list();
print_list();
return 0;
}