2016-02-19 35 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