2010-05-14 6 views
0

나는 C로 프로그램을 만들고 있는데, 나는 메모리에 약간의 문제가 있다고 생각한다.C - 구조체 문제 - 쓰기

내 문제는 : 구조체를 반환하는 2 함수가 있습니다. 한 번에 하나의 함수 만 실행하면 아무런 문제가 없습니다. 하지만 하나씩 실행하면 두 번째 구조체에 writting 할 때 항상 오류가 발생합니다.

기능 struct item* ReadFileBIN(char *name) - 이진 파일을 읽습니다. struct tables* getMesasInfo(char* Filename) - 텍스트 파일을 읽습니다.

#include "stdafx.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <time.h> 

int numberOfTables=0; 
int numberOfItems=0; 

//struct tables* mesas; 
//struct item* Menu; 

typedef struct item{ 
    char nome[100]; 
    int id; 
    float preco; 
}; 
typedef struct tables{ 
    int id; 
    int capacity; 
    bool inUse; 
}; 
struct tables* getMesasInfo(char* Filename){ 
    struct tables* mesas; 
    char *c; 
    int counter,numberOflines=0,temp=0; 
    char *filename=Filename; 
    FILE * G; 
    G = fopen(filename,"r"); 
    if (G==NULL){ 
     printf("Cannot open file.\n"); 
    } 
    else{ 
    while (!feof(G)){ 
    fscanf(G, "%s", &c); 
    numberOflines++; 
     } 
    fclose(G); 
    } 
    /* Memory allocate for input array */ 
    mesas = (struct tables *)malloc(numberOflines* sizeof(struct tables*)); 
    counter=0; 
    G=fopen(filename,"r"); 
    while (!feof(G)){ 
     mesas[counter].id=counter; 
     fscanf(G, "%d", &mesas[counter].capacity); 
     mesas[counter].inUse= false; 
     counter++; 
    } 
fclose(G); 
numberOfTables = counter; 
return mesas; 
} 

struct item* ReadFileBIN(char *name) 
{ 
     int total=0; 
     int counter; 
     FILE *ptr_myfile; 
     struct item my_record; 
     struct item* Menu; 
     ptr_myfile=fopen(name,"r"); 
     if (!ptr_myfile) 
     { 
      printf("Unable to open file!"); 
     } 

     while (!feof(ptr_myfile)){ 
      fread(&my_record,sizeof(struct item),1,ptr_myfile); 
      total=total+1; 
     } 
     numberOfItems=total-1; 
     Menu = (struct item *)calloc(numberOfItems , sizeof(struct item)); 
     fseek(ptr_myfile, sizeof(struct item), SEEK_END); 
     rewind(ptr_myfile); 
     for (counter=1; counter < total ; counter++) 
     { 
      fread(&my_record,sizeof(struct item),1,ptr_myfile); 
      Menu[counter] = my_record; 
      printf("Nome: %s\n",Menu[counter].nome); 
      printf("ID: %d\n",Menu[counter].id); 
      printf("Preco: %f\n",Menu[counter].preco); 
     } 
     fclose(ptr_myfile); 
     return Menu; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    struct item* tt = ReadFileBIN("menu.dat"); 
    struct tables* t = getMesasInfo("Capacity.txt"); 
    getchar(); 
}** 

점점 메신저 오류는 다음과 같습니다 :

"0x00411700에 처리되지 않은 예외 TEST.EXE의 :가 0xc0000005 :. 액세스 위반 쓰기 위치를 0x00000000"

내 코드는 이것이다 "Menu [counter] = my_record;"에서

미리 감사드립니다.

+1

:. 당신이 구조체의 배열에 대한 할당하고 기억하고 당신이 할당되도록 메사는, 첫 번째 요소에 대한 포인터입니다.? 그 위치에서 numberoflines 구조체를위한 메모리. 이 문제를 해결하고 다시 실행하면 우리가 볼 수 있습니다. –

답변

1

당신은이 라인에 문제가 있습니다

numberOfItems=total-1; 
    Menu = (struct item *)calloc(numberOfItems , sizeof(struct item)); 
    fseek(ptr_myfile, sizeof(struct item), SEEK_END); 
    rewind(ptr_myfile); 
    for (counter=1; counter < total ; counter++) 

먼저, 당신은에 numberOfItems을 설정하는 하나보다 작은 보다 작습니다. 이것은 잘못되었습니다.심지어 numberOfItems도 필요하지 않습니다. total이 파일의 줄 수를 가지고 있기 때문에, 다음 줄은 정말 for 루프에서 1부터 배열로 Menu을 사용하려는, Menu = (struct item*) calloc(total, sizeof(struct item));

둘째해야합니다. C 배열은 0 기반입니다. for 루프는 for (counter = 0; counter < total; counter++)이어야합니다.

마지막으로 피터가 지적한 것처럼 첫 번째 함수에서 잘못된 크기의 객체를 할당하고 있습니다. 당신은 numberOfLines*(sizeof(struct tables)를 malloc에 ​​필요 (하지 sizeof(struct tables*)

@Catarrunas가 실제로
+0

당신과 뻬터 덕분에 당신의 해결책이 도움이되었습니다. 객체의 worng 크기가 문제였다. 감사합니다. – Catarrunas

3

당신은 getMesasInfo()에 잘못된 크기의 메모리 블록을 할당하는 것 : 그래서 당신은 쉽게

mesas = (struct tables *)malloc(numberOflines* sizeof(struct tables*)); 

: sizeof(struct tables*)하지 당신이 가리키는 구조체의를 포인터의 크기를 제공합니다 할당되지 않은 메모리를 덮어 씁니다. 적절한 할당하면 ReadFileBIN()의 다른 배열을 할당하는 방식과 유사

mesas = (struct tables *)malloc(numberOflines* sizeof(struct tables)); 

또는이어야한다 : 또한

mesas = (struct tables *)calloc(numberOflines, sizeof(struct tables)); 

을, 나는 그것이 의도적의 여부 모르겠지만, ReadFileBIN() 당신은 (1) 할당 및 레코드의 총 개수보다 (2) 하나 개 적은 기록을 판독 :

numberOfItems=total-1;            // 1 
    Menu = (struct item *)calloc(numberOfItems , sizeof(struct item)); // 1 
    fseek(ptr_myfile, sizeof(struct item), SEEK_END); 
    rewind(ptr_myfile); 
    for (counter=1; counter < total ; counter++)      // 2 
    ... 

루프 카운터 1 (0 대신로부터 시작되기 때문에 C에서 정상적인 것처럼), 루프 total-1 번을 효과적으로 실행합니다. 즉, 배열의 요소 1 ~ total-1을 읽습니다. 그러나 배열의 실제 요소는 0에서 total-2까지 인덱싱되므로 배열의 첫 번째 요소는 초기화되지 않은 상태로 남게되고 결국에는 버퍼 오버플로 오류가 발생합니다.

+0

당신이 얻을 않는 오류가 무엇 –

+0

Thanks many much Peter – Catarrunas

1

더 피터의 입장을 설명하기 위해 :

struct tables { 
    int id; 
    int capacity; 
    int inUse; /* bool is not a C type */ 
}; 

int main() 
{ 
    printf("sizeof: %d\n",sizeof(struct tables*)); 
    printf("sizeof: %d\n",sizeof(struct tables)); 

} 

의지를 출력 :

sizeof: 4 
sizeof: 12 
+0

'stdbool.h'는' – detly

+0

뭔가 typedef를 포함하고 있거나 (컴파일하지 않을 수도 있지만) C 표준의 일부가 아닌 것 같아요. 정말 그 코드를' int'. –