2012-12-14 83 views
1

我在創建這個C程序時得到了一個STATUS_ACCESS_VIOLATION,我相信這是因爲一次初始化結構,然後使用malloc()來增加它們的大小,從而導致已經使用的引用內存指針。這是此異常發生功能:由於malloc()導致的STATUS_ACCESS_VIOLATION?

void process_track(char filename[], struct track *tracks) { 
    int i = 0; 
    FILE* fp; 
    int lines; 
    lines = count_file_lines(filename); 
    tracks = malloc(lines); 
    fp = fopen(filename, "r"); 
    if (fp == NULL) { 
     printf("\n\"%s\" File not found", filename); 
     exit(1); 
    } else { 
     for (i = 0; i < lines; i++) { 
      fscanf(fp, "%d %d %d %d\n", &tracks[i].number, &tracks[i].startnode, &tracks[i].endnode, &tracks[i].minutes); 
     } 
     for (i = 0; i < lines; i++) { 
      printf("%d ", tracks[i].number); 
      printf("%d ", tracks[i].startnode); 
      printf("%d ", tracks[i].endnode); 
      printf("%d\n", tracks[i].minutes); 
     } 
    } 
} 

具體地,它發生在下面的行:

fscanf(fp, "%d %d %d %d\n", &tracks[i].number, &tracks[i].startnode, &tracks[i].endnode, &tracks[i].minutes); 

該函數的調用在下面的函數(情況3):

void get_file(char textfilename[], int optnumber) { 
    struct node *nodes; 
    struct track *tracks; 
    struct course *courses; 
    struct entrant *entrants; 
    struct checkpointdata *checkpointdatas; 
    char filename[20]; //Array of char for filename 
    printf("Enter the name of the %s text file(with file extension) :", textfilename); 
    scanf(" %[a-zA-Z._1-9]", &filename); 
    switch (optnumber) { 
     case 1: 
      process_name(filename); 
      break; 
     case 2: 
      process_node(filename, nodes); 
      break; 
     case 3: 
      process_track(filename, tracks); 
      break; 
     case 4: 
      process_course(filename, courses); 
      break; 
     case 5: 
      process_entrant(filename, entrants); 
      break; 
     case 6: 
      process_checkpointdata(filename, checkpointdatas); 
      break; 
    } 

} 

它讀取的第一行很好,但在此之後失敗。由於其他「process_ [data]」非常相似,我也嘗試了這些。有些可以正常工作,有些會想出異常,有些會在輸出中檢索垃圾。

我將如何解決這個問題,或者分配內存,以便它不會與預先分配的內存衝突(如果這確實是問題)?

+0

您忘記關閉您打開的文件。它與你的崩潰無關,但你現在應該學習良好的習慣。 –

回答

2

malloc()接受要分配的字節數,而不是元素數。張貼的代碼僅分配lines字節:

tracks = malloc(lines); 

這是不夠的的struct track陣列,並且將導致在隨後的循環for寫入和從超出分配的內存塊的邊界讀取。通過元素的尺寸以及元件的數量:

tracks = malloc(lines * sizeof(*tracks)); 

注意函數內tracks所做的任何改變只給這個函數是可見的。由於tracks在調用函數之後實際上並不使用,所以可以用局部變量替換參數。

記住每個malloc()必須有一個free()

+0

我現在明白了 - 非常感謝您的工作!關於丟失對「軌道」的更改,爲什麼這些更改會在'process_track()'函數之外丟失,因爲它是通過'* tracks'指針工作的?這是否意味着我必須返回指針? – Wilko

+0

@Wilko,指針也通過C中的值傳遞。要更改指針指向函數中的內容,並使其在函數外可見,您需要傳遞指針的地址。或者,你也可以返回一個指針。 – hmjd

+0

感謝您的進一步幫助!是否有我無法改變'process_track(filename,tracks);'process_track(filename,&tracks);'將地址傳遞給函數的原因? – Wilko