未知数の生徒レコードがバイナリで書かれたファイルから読み込み、GPAで生徒をソートしてstdoutに送信する必要があります。ポインタへのポインタにrealloc()を使用するとポインタ値が変化する
当社のソート機能は、私が学生(おそらく最良の解決策へのポインタへのポインタを使用することを選択した理由です
void insertion_sort(Student **, int);
は?私は私の好きな学生へのポインタを送っただけかもしれないと思うようになりましたこの(&p_to_Student, n)
?)
コードは、p
が最初の学生名(最初の学生名)を指している最初の要素を印刷すると、私は気が散ってしまい、他の生徒は問題ありません。
私はp
の値をチェックし、それがrealloc()
後に変化しないが呼び出され、それはまた、p
の最初の要素のアドレス(右?)だからさ。
また、Valgrindと一緒にチェックして、メモリリークに関する一連のエラーを返します。
realloc()
コールがないときにコードが正常に実行されます。また、ファイルを読み終えた後にp
を初期化するときもコードは正常に実行されます。だから、realloc()
を正しく使用していないことと関係しているはずです。
ボーナスの質問:これは、ファイルから不明なデータエントリを読み取るための適切な方法ですか?
#include <stdio.h>
#include <stdlib.h>
struct student {
char name[30];
char surname[30];
double GPA;
};
typedef struct student Student;
void insertion_sort(Student **arr, int n)
{
int i,j;
for (i=1; i<n; i++)
{
Student *tmp = arr[i];
for (j=i; j>0 && (tmp->GPA > arr[j-1]->GPA); j--)
arr[j] = arr[j-1];
arr[j] = tmp;
}
}
int main(int argc, char **argv)
{
FILE *in;
Student s, *arr, **p;
size_t ret;
int i = 1, n=0, c=2;
in = fopen(argv[1], "rb");
if (in == NULL)
return printf("Can't open file!\n"), 1;
arr = (Student*) malloc(c*sizeof(Student*));
p = (Student**) malloc(c*sizeof(Student*));
do
{
ret = fread(&s, sizeof(Student), 1, in);
if (ret)
{
if (n == c)
{
arr = (Student*) realloc(arr, (c*=2)*sizeof(Student));
p = (Student**) realloc(p, c*sizeof(Student*));
}
// when I print the value of pointer p
// the values is changed when realloc() is called
printf("p = %p\n", p);
arr[n] = s;
p[n] = arr+n;
n++;
}
} while (ret);
fclose(in);
// If I do this instead the program runs correctly
//p = (Student**) malloc(c*sizeof(Student));
//for (int i=0; i<n; i++)
//{
//p[i] = arr+i;
//}
insertion_sort(p, n);
for (i=0; i<n; i++)
{
printf("%2d. %-20s %-20s %7.2lf\n", i+1, p[i]->name,
p[i]->surname, p[i]->GPA);
}
free(arr);
free(p);
return 0;
}
検索バーにreallocと入力するだけで、動作方法に複数のヒットが得られます。あなた自身で答えを見つけようとしなかったことは明らかです。 – Pemdas
'realloc'はポインタを変更することがあります。つまり、そのポインタへのポインタはすべて無効になる可能性があります。あなたの場合、 'p'は' arr'へのポインタを保持します。あなたのソートのためだけに 'p'が必要なので、あなたがコメントしたアプローチ - ソートする前に' p'を割り振る方が良いです。'realloc'はあなたの配列がどれほど大きいかを事前に知らないと便利です。 –
@Pemdas私は信じています。もし私が逃した 'realloc()'の動作のどの部分を指してください。 –