【问题标题】:How do I avoid this back trace error after my program displays its output?在我的程序显示其输出后,如何避免此回溯错误?
【发布时间】:2020-04-11 00:54:53
【问题描述】:

这是我正在尝试实施的详细程序: 一位博物学家要去探索亚马逊丛林,他需要一个计算机程序来记录所有发现的新物种的信息。对于每个新物种,必须存储名称(最多 128 个字符)、大小(实数)和动物类型。哺乳动物、昆虫、鸟类或鱼类)。 这是示例运行的样子(键盘输入以斜体显示)...

> NewSpecies
Enter animal information ("exit" to exit)
What is the name : bloatfish
What is the size : 12.47
What is the type : fish
Enter animal information ("exit" to exit)
What is the name : stingybeasty
What is the size : 0.13
What is the type : insect
Enter animal information ("exit" to exit)
What is the name : toothfulsloth
What is the size : 33.33
What is the type : mammal
Enter animal information ("exit" to exit)
What is the name : exit

The following new species were found:
bloatfish            has size  12.47 and is a fish
stingybeasty         has size   0.13 and is a insect
toothfulsloth        has size  33.33 and is a mammal 
You must ...
Implement the program in C.

必须使用结构数组,以便每个新物种都可以记录在数组的一个元素中。 动物的类型表示为枚举类型,表示哺乳动物、昆虫、鸟类或鱼类中的一种。 事先不知道会发现多少新物种,所以程序必须 malloc 为一个大小为 1 的初始数组,并根据需要使用加倍 realloc 技术来获取更多内存。您必须始终检查 malloc 的返回值,就像在 Malloc 包装函数中所做的那样(或者只使用 Malloc :-)。

我的尝试:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>

    #define MAX_CHAR 128
    #define LENGTH(A) (sizeof(A)/sizeof(A[0]))

    typedef char String[MAX_CHAR];
    typedef enum {mammal, insect, bird, fish, error} AnimalType;

    typedef struct{
      String name;
      double size;
      AnimalType type;
    } Animal;

    void * Malloc(size_t Size) {

        void * Memory;

        if ((Memory = malloc(Size)) == NULL) {
            perror("Cannot malloc");
            exit(EXIT_FAILURE);
        } else {
            return(Memory);
        }
    }

    AnimalType CheckAnimalType(String type) {
        if (!strcmp(type,"mammal")) {
            return (mammal);
        }
        if (!strcmp(type,"insect")) {
            return (insect);
        }
        if (!strcmp(type,"bird")) {
            return (bird);
        }
        if (!strcmp(type,"fish")) {
            return (fish);
        }
        return (error);
    }

    char *PrintAnimalType(AnimalType type){
      switch(type){
        case mammal: return "mammal"; break;
        case insect: return "insect"; break;
        case bird: return "bird"; break;
        case fish: return "fish"; break;
        case error: return "error";
      }
      return "error";

    }
    void printData(Animal *animal, int size) {
        printf("The following species were found:\n");
        for(int i = 0; i < size-1; i++)
            printf("%s has size %.2lf and is a %s\n", animal[i].name, animal[i].size, PrintAnimalType(animal[i].type));
    }

    void MainMenu(Animal *animal, int *size){
      for(;;){
        Animal newAnimal;
        String animalName;
        double animalSize;
        String animalType;

        printf("Enter animal information (\"exit\" to exit)\n");

        printf("What is the name : ");
        scanf("%s", animalName);
        if(!strcmp(animalName, "exit")) break;
        strcpy(newAnimal.name, animalName);

        printf("What is the size : ");
        scanf("%lf", &animalSize);
        if(newAnimal.size == 0) break;
        newAnimal.size = animalSize;

        printf("What is the type : ");
        scanf("%s", animalType);
        newAnimal.type = CheckAnimalType(animalType);

        if((animal = realloc(animal, sizeof(newAnimal)*((*size)+1))) == NULL) {
                printf("MEMORY ERROR: problem reallocating array\n");
                return;
            }
         animal[(*size)-1] = newAnimal;
            (*size)++;
      }
      printData(animal, *size);
    }



    int main(void) {
      int size = 1;
      Animal *animal = Malloc(sizeof(Animal));
      MainMenu(animal, &size);
      free(animal);
      return 0;
    }

我正在尝试在 C 中实现上述内容,但执行后直接出现此错误:

错误链接:https://pastebin.com/Wcu0wtet

【问题讨论】:

  • 错误转储应包含为文本,而不是图像。
  • 请在此之前显示程序日志。也就是说,你输入了什么,程序走了多远?

标签: c pointers memory-management memory-leaks


【解决方案1】:

MainMenu 中,您在animal 上致电realloc。这可能会调整现有缓冲区的大小,但通常会分配一个新的缓冲区,从而更改指针的值。新指针存储在本地animal 变量中,而不是main 中的变量。

当您返回main 时,您调用free(animal),它将尝试释放已通过调用realloc 释放的原始动物缓冲区。

您需要将修改后的缓冲区指针作为返回值或通过将指针传递给原始变量 (Animal **) 传递回调用方。

【讨论】:

  • 非常感谢!!!我在这上面花了 6 个多小时。我将 free(animals) 删除到 MainMenu 并修复了所有问题
猜你喜欢
  • 1970-01-01
  • 2022-10-17
  • 1970-01-01
  • 1970-01-01
  • 2014-06-03
  • 1970-01-01
  • 2013-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多