2016-02-19 59 views
0

我一直在用這個結構撞擊我的頭在牆上。我能夠縮小到我的代碼的realloc部分。Realloc:在結構中重置結構的可彎曲陣列

CalStatus readCalComp(FILE *const ics, CalComp **const pcomp) 
    { 
    CalStatus test; 
    CalProp * foldLine; 
    CalProp * temp; 
    CalComp ** subComp; 
    char * buffer; 
    static int depth = 0; 
    int count = 0; 
    int i = 0; 

    buffer = NULL; 
    foldLine = NULL; 
    subComp = NULL; 

    if (depth == 0) 
    { 
     test = readCalLine (ics, &buffer); 

     if (buffer == NULL) 
     { 
      return test; 
     } 
     foldLine = malloc (sizeof (CalProp)); 
     assert (foldLine != NULL); 
     test.code = parseCalProp (buffer, foldLine); 
     free (buffer); 

     if ((strcmp ("BEGIN", foldLine->name) == 0) && ((strcmp ("VCALENDAR", foldLine->value) == 0))) 
     { 
      (*pcomp)->name = malloc (sizeof(char) * strlen(foldLine->value)+1); 
      assert ((*pcomp)->name != NULL); 
      strcpy((*pcomp)->name, foldLine->value); 
      depth = depth + 1; 

      free(foldLine->name); 
      free(foldLine->value); 
      free(foldLine); 

      while ((buffer != NULL) && (test.code == OK) && (depth > 0)) 
      { 
       test = readCalLine (ics, &buffer); 

       if (buffer != NULL) 
       { 
        foldLine = malloc (sizeof(CalProp)); 
        assert (foldLine != NULL); 
        test.code = parseCalProp (buffer, foldLine); 
        free (buffer); 

        if ((strcmp ("END", foldLine->name) == 0) && ((strcmp ("VCALENDAR", foldLine->value) == 0) || (strcmp ("VCALENDAR\r\n", foldLine->value) == 0))) 
        { 
         depth = depth - 1; 

         free(foldLine->name); 
         free(foldLine->value); 
         free(foldLine); 

         return test; 
        } 
        else if (strcmp ("BEGIN", foldLine->name) == 0) 
        { 
         subComp = malloc(sizeof (CalComp *)); 
         *subComp = malloc(sizeof(CalComp) + (1*sizeof(CalComp*))); 

         (*subComp)-> name = NULL; 
         (*subComp)-> nprops = 0; 
         (*subComp)-> prop = NULL; 
         (*subComp)-> ncomps = 0; 
         (*subComp)-> comp[0] = NULL; 

         (*subComp)-> name = malloc(sizeof(char) *strlen(foldLine->value)+1); 
         strcpy((*subComp)->name, foldLine->value); 

         if ((*pcomp)-> ncomps == 0) 
         { 
          (*pcomp)->comp[(*pcomp)->ncomps] = *subComp; 
          (*pcomp)->ncomps += 1; 
         } 
         else 
         { 
          (*pcomp)->ncomps += 1; 
          *pcomp = realloc(*pcomp, sizeof(CalComp) + (2*sizeof(CalComp*))); 
          (*pcomp)->comp[(*pcomp)->ncomps-1] = *subComp; 
         } 

         depth = depth + 1; 

         test = readCalComp (ics, subComp); 
        } 
       } // end of if buffer NULL 
      }// end of While 
     } // end of if VCALENDAR 
    } // End of if Depth 
    else 
    { 
     if (count == 0) 
     { 
      test = readCalLine (ics, &buffer); 
      count += 1; 
     } 

     while ((test.code == OK) && (buffer != NULL)) 
     { 
      if (count != 1) 
      { 
       test = readCalLine (ics, &buffer); 
      } 
      else 
      { 
       count = 0; 
      } 

      if (buffer != NULL) 
      { 
       foldLine = malloc (sizeof(CalProp)); 
       test.code = parseCalProp (buffer, foldLine); 
       free (buffer); 

       if ((strcmp ("END", foldLine->name) == 0) && ((strcmp ((*pcomp)->name, foldLine->value) == 0))) 
       { 
        depth = depth - 1; 

        free (foldLine->name); 
        free (foldLine->value); 
        free (foldLine); 

        return test; 
       } 
       else if (strcmp ("BEGIN", foldLine->name) == 0) 
       { 
        printf("Success in malloc 2!\n"); 
        subComp = malloc(sizeof (CalComp *)); 
        *subComp = malloc(sizeof(CalComp) + (1*sizeof(CalComp*))); 

        (*subComp)-> name = NULL; 
        (*subComp)-> nprops = 0; 
        (*subComp)-> prop = NULL; 
        (*subComp)-> ncomps = 0; 
        (*subComp)-> comp[0] = NULL; 

        (*subComp)-> name = malloc(sizeof(char) *strlen(foldLine->value)+1); 
        strcpy ((*subComp)->name, foldLine->value); 

        if ((*pcomp)-> ncomps == 0) 
        { 
         (*pcomp)->comp[(*pcomp)->ncomps] = *subComp; 
         (*pcomp)->ncomps += 1; 
        } 
        else 
        { 
         (*pcomp)->ncomps += 1; 
         (*pcomp) = realloc(*pcomp, sizeof(CalComp) + (2*sizeof(CalComp*))); 
         (*pcomp)->comp[(*pcomp)->ncomps-1] = *subComp; 
         printf ("First subcomponent is %s\n", (*pcomp)->comp[0]->name); 
         printf ("Second subcomponent is %s\n", (*pcomp)->comp[1]->name); 
        } 

        depth = depth + 1; 

        test = readCalComp (ics, subComp); 
       } 
      } 
     } 
    } 

     return test; 
    } 

CalComp系統是由一個結構:

char * name; 

int numProps; 

CalProp *prop (linked list); 

int numComp; 

CalComp *comp[] (flexible array); 

檢查函數內部,靈活的陣列內的結構的名稱是正確的,但是當我嘗試訪問外部的名字函數,它可以是NULL值,也可以設置爲結構的第一個鏈表節點的名稱。

由於賦值的性質,我無法修改Calcomp結構和函數參數。函數必須是遞歸的,並且靈活數組必須根據需要進行調整。

正如我之前所說的,我通過打印靈活數組中的值來縮小到realloc範圍。程序重新分配時發生該錯誤。我試圖重新分配到一個臨時變量,檢查是否爲NULL,然後將其分配給pcomp但沒有幫助。

+1

你有很多重複的代碼初始化'CalComp'和'CalProp'。在處理結構時,我總是寫一個'structname_new'和一個'structname_destroy'來封裝那些代碼中有時候很棘手的部分。嘗試這樣做,看看這是否更容易調試。如果沒有,請使用更好的封裝代碼重新發布您的問題。 – Schwern

+0

我只想提一提,所有可用的函數都會導致包含END的靈活數組名稱。 – Mog

+0

我想清楚是什麼導致了這個問題。當我在遞歸調用中使用realloc時,它可能會更改內存地址位置。由於遞歸調用,沒有任何東西可以捕獲父節點中地址的變化。因此它充滿了垃圾。人很煩人。通過使用靜態幫助函數來固定地址,並在遞歸調用返回後將其放回。 – Mog

回答

1

當您致電realloc時,您不包括ncomp在靈活結構的額外大小,你只是硬編碼到2

(*pcomp) = realloc(*pcomp, sizeof(CalComp) + (*pcomp->ncomps * sizeof(CalComp*))); 
+0

我刪除了(* pcomp) - > ncomps以查看它是否有不良數據。不過謝謝。 – Mog

0

(*pcomp) = realloc(*pcomp, sizeof(CalComp) + (2*sizeof(CalComp*)));

改變上述行來

pcomp = realloc(*pcomp, sizeof(CalComp) + (2*sizeof(CalComp*))); 
+0

不起作用。分配只讀參數'pcomp'。不過謝謝。 – Mog