2016-08-29 2 views
-2

私はこの病院管理プログラムを学校の仕事に費やそうとしていますが、私はこのエラーがあり、解決方法は本当に分かりません。誰かが私を案内することに感謝します。 ありがとうございます。いくつかの変数をC言語のバイナリファイルに保存しているときにエラーが発生しました

私は、このリンクリストがあります:

struct marcacao 
{ 
    char nome[50]; 
    int idade; 
    struct marcacao *next; 
}; 

この機能

void make_apt(struct marcacao **head_apt) 

struct marcacao tmp; 
... 
    while(*head_apt) 
    head_apt = &(*head_apt)->next; 
... 
printf("Nome do Paciente > "); 
scanf(" %[^\n]", tmp.nome); 
printf("Idade do Paciente > "); 
scanf("%d", &tmp.idade); 

tmp.next = NULL; 

if (!(*head_apt = malloc(sizeof (**head_apt)))) 
{ 
    printf("Erro a alocar novo no "); 
    return; 
} 
**head_apt = tmp; 
... 

を使用して作成され、それは次回に再開することができるので、私は、バイナリファイルに情報を保存する必要があります実行。

void sv_apt(struct marcacao *head_apt) 

FILE *f = fopen(APT_FILE, "wb"); 
... 

while(head_apt) 
{ 
    fwrite(head_apt->nome, sizeof(head_apt->nome), 1, f); 
    fwrite(&head_apt->idade, sizeof(head_apt->idade), 1, f); 
    head_apt = head_apt->next; 
} 

しかし、valgrindのは、これをshoingさ:

==18255== Syscall param write(buf) points to uninitialised byte(s) 
==18255== at 0x4F22710: __write_nocancel (syscall-template.S:81) 
==18255== by 0x4EAFF02: [email protected]@GLIBC_2.2.5 (fileops.c:1261) 
==18255== by 0x4EB13DB: new_do_write (fileops.c:538) 
==18255== by 0x4EB13DB: [email protected]@GLIBC_2.2.5 (fileops.c:511) 
==18255== by 0x4EB0C5F: [email protected]@GLIBC_2.2.5 (fileops.c:165) 
==18255== by 0x4EA4A4F: [email protected]@GLIBC_2.2.5 (iofclose.c:59) 
==18255== by 0x401CD3: sv_apt (apt.c:125) 
==18255== by 0x401A11: make_appointment (apt.c:43) 
==18255== by 0x400B20: main (main.c:31) 
==18255== Address 0x402700c is not stack'd, malloc'd or (recently) free'd 
==18255== 

そして、私は情報がうまく保存されていないことがわかりますバイナリエディタを使用して。

+3

*リンゴ*と*オレンジ*を混ぜて表示されます。 'struct marcacao tmp;'は、自動ストレージを持つ関数に対してローカル宣言されているようです。それはリンクされたistのノードとして割り当てられます。あなたのコードの別の部分に値を書き込もうとすると、 'tmp'を使ってリストに割り当てたノードを見つけることができないので、それは壊滅します。しかし、*** MCVE ***なしでは確かめることは不可能です。 [**最小限で完全で検証可能なサンプルの作成方法**](http://stackoverflow.com/help/mcve)を参照してください。 (自分自身や他の人がさらに助けてくれるかもしれません) –

+0

さらに、「valgrind」はまさにそれを言っているようです。そのアドレス0x402700cはスタックされていません、malloc'd、...(現在使用中のメモリや最近解放されたメモリとしては見えません)。この問題は 'main()'の 'make_appointment()'行と '(file.c:line no。)'に示されているファイルで、コード内で生成されます。 –

+0

注: 'scanf("%[^ \ n] "、tmp.nome);は' gets(tmp.nome) 'と同じくらい危険です。 'fgets()'を使う方が良い方法でしょう。 – chux

答えて

1

「シリアライゼーション」の考え方を理解する必要があります。これは、データをファイル(またはワイヤ)に格納して読み戻すことです。あなたはファイルに物をダンプすることはできません(まれなv単純な場合を除いて)。

シリアル化形式を選択する必要があります。 ASCIIベースのものをお勧めします。 json、xml、またはyamlを使用します。

+1

この場合を除いて、 'struct marcacao'のリンクリストをバイナリ形式のディスクに簡単にダンプし、それを問題なくリストに簡単に読み込むことができます。 –

+0

「次の」ポインタをいくつかの抽象的なポインタのコンセプトに変換して、同じアドレスにロードされないために変換する必要があります。 – pm100

+0

いいえ、私たちは通信していない場所だと思います。あなたの言ってる事がわかります。私はファイルにポインタを書くことについて話しているわけではなく、単に各構造体(すべてのメンバーは自動ストレージを使用しているので、ポインタの問題はありません)を読んでいます。構造体を呼び出し、リストを再構築する 'add_node'を呼び出します。あなたは正しいです、ノードまたは次のアドレスをファイルに書き込むことはできず、それらを読み込むことができます。 –

関連する問題