【问题标题】:Typecasting pointers in linked list of structures结构链表中的类型转换指针
【发布时间】:2012-11-27 13:13:18
【问题描述】:

问题表明我需要两个结构,STRUCTURE1 和 STRUCTURE2(我知道原来的)。 STRUCTURE1 包含 5 个浮点值(不是数组)和一个指针。 STRUCTURE2 保存 1 个浮点值和一个指向另一种 STRUCTURE2 类型的指针。我还需要一个指针数组,其中每个元素都指向一个 STRUCTURE1。然后每个第一个 STRUCTURE1 都指向另一个 STRUCTURE1,然后 THAT STRUCTURE1 需要指向一个 STRUCTURE2(这是类型转换的来源)。

下面是我的代码的重要部分,问题(至少我遇到错误的地方)出在 printToFile() 的 trav2 = (STRUCT2*)trav1->next; 部分,我遇到了分段错误。

   void main(){
      STRUCT1 *ptr[20] = {NULL};  //Array of pointers that point to type STRUCT1
      float min, max;
      int i, j, answer;
      for(i = 0; i < 19; i++){   //19 to leave the 20th array spot for NULL
        printf("\nWould you like to add 2 more sets of numbers?\n");
        printf("1: Yes\n");
        printf("2: No\n");
        scanf("%d", &answer);
        if(answer == 1){
          printf("\nFirst set of numbers:\n");
          ptr[i] = getData();
          printf("\nSecond set of numbers:\n");
          ptr[i]->next = getData();
          min = getMin(ptr[i]);
          max = getMin(ptr[i]->next);
          STRUCT2 *trav;
          trav = (STRUCT2*)malloc(sizeof(STRUCT1));
          trav = (STRUCT2*)ptr[i]->next;
          trav->next = assignMin(min);
          trav = trav->next;
          trav->next = assignMax(max);
        }else{
          break;
        }
      }
      printToFile(ptr);
      printf("\nProgram Done\n");
    }

STRUCT1* getData(){
  STRUCT1 *newStruct;
  newStruct = (STRUCT1*)malloc(sizeof(STRUCT1));
  float num;
      printf("Enter number 1: ");
      scanf("%f", &num);
      newStruct->f1 = num;
      printf("Enter number 2: ");
      scanf("%f", &num);
      newStruct->f2 = num;
      printf("Enter number 3: ");
      scanf("%f", &num);
      newStruct->f3 = num;
      printf("Enter number 4: ");
      scanf("%f", &num);
      newStruct->f4 = num;
      printf("Enter number 5: ");
      scanf("%f", &num);
      newStruct->f5 = num;

      return newStruct;
}

void printToFile(STRUCT1 *ptr[]){
  FILE *f;
  f = fopen("structure.txt", "w");
  int i, j;
  STRUCT1 *trav1;
  STRUCT2 *trav2;
  trav1 = (STRUCT1*)malloc(sizeof(STRUCT1));
  trav2 = (STRUCT2*)malloc(sizeof(STRUCT2));

  for(i = 0; i < 20; i++){
    fprintf(f, "%.3f,%.3f,%.3f,%.3f,%.3f\n", ptr[i]->f1, ptr[i]->f2, ptr[i]->f3, ptr[i]->f4, ptr[i]->f5);
    trav1 = ptr[i]->next;
    fprintf(f, "%.3f,%.3f,%.3f,%.3f,%.3f\n", trav1->f1, trav1->f2, trav1->f3, trav1->f4, trav1->f5);
    trav2 = (STRUCT2*)trav1->next;
    fprintf(f, "Minimum of first number set: %.3f\n", trav2->f1);
    trav2 = trav2->next;
    fprintf(f, "Maximum of second number set: %.3f\n", trav2->f1);
    fprintf(f, "\n");    
  }
}

这可能都是非常非常错误的,但我的教授从未谈论过指向不同类型的指针,而且关于结构的部分也很短。希望它没有完全拙劣,只需要在这里和那里做一些事情。

有人认为他们知道哪里出了问题吗?

【问题讨论】:

  • 看来他也从未谈论过free()。除此之外,如果您在问题的代码部分中包含结构定义,可能会有助于提高可读性。
  • 很多 错误,从不完整的代码开始。 assignMin()assignMax() 均未包含在帖子中,结构也是如此。您在不需要的地方动态分配内存,并且在需要的地方,您会立即用未初始化的值覆盖分配(例如trav = (STRUCT2*)malloc(sizeof(STRUCT1));,紧随其后的是trav = (STRUCT2*)ptr[i]-&gt;next;,您永远不会为@ 中的分配初始化newStruct-&gt;next 987654329@,而且这里没有free()。我建议在调试器和教科书中花一些时间认真
  • 我意识到代码真的很糟糕。它也是结构和链表的第一个赋值。我没有包含结构代码或其他函数,因为那不是问题所在,结构只有浮点值的定义。从那以后,我使程序工作,可能不是以最有效的方式,但我摆脱了无用的内存分配并增加了内存释放。如果我糟糕的编码冒犯了任何人,我深表歉意,但我非常感谢您的帮助,因为它确实帮助了我。
  • 无意冒犯,扎克。越早发现问题所在,就越早学会如何做对。 (a) 从已知良好的代码示例和样式中学习和 (b) 编写自己的代码相结合,将大有帮助。有一些蹩脚的书或教授说“这就是方式”是一回事。但我不能再强调这一点:从已知良好的代码中学习。在您怀疑不太好的代码中寻找漏洞和问题,最重要的是,学习良好的调试习惯。后者似乎在学术界完全被忽略了,这很可惜。没有什么比找到错误的可靠方法更能为您服务了。
  • 明智的做法是将STRUCT1 拆分为STRUCT1aSTRUCT1b,并让STRUCT1a 有一个指向STRUCT1b 的指针,而STRUCT1b 有一个指向STRUCT2 的指针。

标签: c pointers linked-list segmentation-fault structure


【解决方案1】:

我认为你的问题出在这一行:

trav = (STRUCT2*)malloc(sizeof(STRUCT1));  

在这里,tray 作为STRUCT2 指针并为STRUCT1 分配内存。最好使用sizeof(STRUCT2)

【讨论】:

    【解决方案2】:

    问题中没有足够的信息,缺少结构定义和填充这些结构的代码。演员表不一定是错的。但是,您可以使用不同的指针来访问任一类型的结构:

       if (ptr->next_st1 != NULL) {
          trav1 = ptr->next_st1;
       } else if (ptr->next_st2 != NULL) {
          trav2 = ptr->next_st2;
       }
    

    作为旁注,您在此处进行的分配:

      trav1 = (STRUCT1*)malloc(sizeof(STRUCT1));
      trav2 = (STRUCT2*)malloc(sizeof(STRUCT2));
    
      for(i = 0; i < 20; i++){
        /* ... */
        trav1 = ptr[i]->next;
        /* ... */
    

    不是必需的,因为您将指针分配给已分配的区域 (trav1 = ptr[i]-&gt;next)。由于此分配,您正在泄漏内存,因为您丢失了指向 malloced 块的指针。在这种情况下,malloc 不是必需的,但在必要时您应该有相应的 free() 调用。

    【讨论】:

    • 这不仅仅是因为那个任务。假设已修复,它仍然会泄漏,因为此源中的任何地方都没有 free()
    猜你喜欢
    • 2016-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    相关资源
    最近更新 更多