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== 

그리고이 정보를 잘 저장되지 않습니다 것을 볼 수있는 16 진수 편집기를 사용하여.

+3

* 사과 *와 * 오렌지 *가 섞인 것 같습니다. 'struct marcacao tmp;'는 자동 저장 기능이있는 로컬에서 선언 된 것처럼 보입니다. 그런 다음 링크 된 노드에서 노드로 지정됩니다. 코드의 다른 부분에 값을 쓰려고하면 'tmp'를 사용하여 목록에 할당 한 노드를 찾을 수 없으므로 부러집니다. 그러나 *** MCVE *** 없이는 확신 할 수 없습니다. [** 최소, 완전하고 검증 가능한 예제를 만드는 방법 **] (http://stackoverflow.com/help/mcve)를 참조하십시오. (그때 나 자신이나 다른 사람이 더 도움을 줄 수 있습니다) –

+0

또한, 'valgrind'는 정확히 말하고있는 것 같습니다. 그 '주소 0x402700c stack'd, 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'를 호출하여 목록을 다시 작성하십시오. 당신이 맞습니다, 당신은 노드 또는 다음 주소를 파일에 쓸 수 없으며 그 주소를 다시 읽을 수 있습니다. –

관련 문제