2010-05-14 114 views
0

我正在用C語言編寫一個程序,我覺得在內存方面有些麻煩。C - struct problems - writing

所以我的問題是:我有2個函數返回一個結構。當我一次只運行一個功能時,我沒有任何問題。但是當我一個接一個地運行時,在寫入第二個結構時總會遇到錯誤。

功能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的未處理的異常:0000005:訪問衝突寫入位置00000000」

in「Menu [counter] = my_record;」

在此先感謝。

+1

什麼是你得到的錯誤 – 2010-05-14 15:41:43

回答

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在文件中的行數,下一行確實應該Menu = (struct item*) calloc(total, sizeof(struct item));

其次,你要使用Menu作爲基於一個數組循環。 C數組是基於零的。你應該有for循環使用for (counter = 0; counter < total; counter++)

最後,正如Peter指出的,在第一個函數中,您將分配錯誤大小的對象。你需要的malloc numberOfLines*(sizeof(struct tables)(不sizeof(struct tables*)

+0

感謝你和Péter,你的解決方案幫助了我,櫃檯對象的工作尺寸是問題所在。 謝謝。 – Catarrunas 2010-05-14 15:55:53

3

你似乎在getMesasInfo()分配錯誤大小的內存塊:sizeof(struct tables*)給你指針的大小,而不是它指向的結構體:

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

讓您輕鬆覆蓋未分配的內存。正確的分配應該是

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

,或者類似於你如何分配在ReadFileBIN()其他數組:

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

事實上@Catarrunas:?還記得你的分配結構體數組,和檯面是指向第一個元素,所以你分配內存爲numberoflines結構在那個位置 雖然我們確實需要知道確切的錯誤修復此問題並再次運行,我們將看到 – 2010-05-14 15:50:49

+0

非常感謝Peter – Catarrunas 2010-05-14 15:56:51

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'定義了一個' bool'類型 – detly 2010-05-14 16:28:05

+0

我確定他包含typedefs到某個東西(或者它不會編譯),但它不是C標準的一部分,我只是試圖說明我已經把它改成了' int'。 – 2010-05-14 16:37:57