【问题标题】:How to allocate memory for my data structure in C如何在 C 中为我的数据结构分配内存
【发布时间】:2016-04-04 22:58:12
【问题描述】:

我不明白为什么我的代码会在用户输入数据后打印出垃圾变量。在我的 C 类入门中学习数据结构、链表和内存分配的过程中。感谢您的帮助!

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

typedef struct AutoMobilesInfo
{
    char *Manufacturer, *ModelNameOfCar, *ColorOfCar;
    int YearOfCar;
    struct AutoMobilesInfo *next;
} Car;

void EnterCarInfo(Car *Info)
{
    Info = (Car *)malloc(sizeof(Car));
    Info->Manufacturer = (char *)malloc(12 *(sizeof(char)));
    Info->ModelNameOfCar = (char *)malloc(12 *(sizeof(char)));
    Info->ColorOfCar = (char *)malloc(12 *(sizeof(char)));

    printf("Please enter the car's manufacturer: \n");
    scanf(" %s", Info->Manufacturer);
    printf("Please enter the car's model: \n");
    scanf(" %s", Info->ModelNameOfCar);
    printf("Please enter the car's color: \n");
    scanf(" %s", Info->ColorOfCar);
    printf("Please enter the year the car was made: \n");
    scanf("%d", &Info->YearOfCar);
}

void PrintedOutCarInfo(Car *host)
{
    host = (Car *)malloc(sizeof(Car));
    host->Manufacturer = (char *)malloc(12 *(sizeof(char)));
    host->ModelNameOfCar = (char *)malloc(12 *(sizeof(char)));
    host->ColorOfCar = (char *)malloc(12 *(sizeof(char)));

    printf("The car's manufacturer is %s\n", host->Manufacturer);
    printf("The car's model is %s\n", host->ModelNameOfCar);
    printf("The color of the car is %s\n", host->ColorOfCar);
    printf("The year the car was made is %d\n", host->YearOfCar);
}

int main()
{
    Car *Car1;
    Car1 = (Car *) malloc(sizeof(Car));
    EnterCarInfo(Car1);
    PrintedOutCarInfo(Car1);
    free(Car1);

    return 0;
}

【问题讨论】:

    标签: c pointers data-structures malloc


    【解决方案1】:

    您正在覆盖PrintedOutCarInfo 中的指针。这一行

    host = (Car *)malloc(sizeof(Car));
    

    还有这一行

    Info = (Car *)malloc(sizeof(Car));
    

    分配你传入的变量hostInfo。把那个函数改成这个

    void PrintedOutCarInfo(Car *host) {
      printf("The car's manufacturer is %s\n", host->Manufacturer);
      printf("The car's model is %s\n", host->ModelNameOfCar);
      printf("The color of the car is %s\n", host->ColorOfCar);
      printf("The year the car was made is %d\n", host->YearOfCar);
    }
    

    你也不应该对 malloc 的返回值进行大小写,而是这样做......

     Info = malloc(sizeof(Car));
    

    试试这个...

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <malloc.h>
    
    typedef struct AutoMobilesInfo
    {
      char *Manufacturer, *ModelNameOfCar, *ColorOfCar;
      int YearOfCar;
      struct AutoMobilesInfo *next;
    } Car;
    
    void EnterCarInfo(Car *Info)
    {
      Info->Manufacturer   = malloc(12 * (sizeof(char)));
      Info->ModelNameOfCar = malloc(12 * (sizeof(char)));
      Info->ColorOfCar     = malloc(12 * (sizeof(char)));
    
      printf("Please enter the car's manufacturer: \n");
      scanf(" %s", Info->Manufacturer);
      printf("Please enter the car's model: \n");
      scanf(" %s", Info->ModelNameOfCar);
      printf("Please enter the car's color: \n");
      scanf(" %s", Info->ColorOfCar);
      printf("Please enter the year the car was made: \n");
      scanf("%d", &Info->YearOfCar);
    }
    
    void PrintedOutCarInfo(Car *host) {
      printf("The car's manufacturer is %s\n", host->Manufacturer);
      printf("The car's model is %s\n", host->ModelNameOfCar);
      printf("The color of the car is %s\n", host->ColorOfCar);
      printf("The year the car was made is %d\n", host->YearOfCar);
    }
    
    int main()
    {
      Car *Car1 = malloc(sizeof(Car));
      EnterCarInfo(Car1);
      PrintedOutCarInfo(Car1);
      free(Car1);
      return 0;
    }
    

    【讨论】:

    • 第一个问题,如果我没有包含头文件 malloc.h,code:blocks 中的编译器如何理解 malloc 函数?第二个问题,为什么我不需要先为我的数据结构分配内存?如,我看到你是如何删除我的 EnterCarInfo() 函数中的第一行的。
    • 我不知道你是否需要malloc.h。我不在我的机器上。如果您确实将其添加回来。您已经在 main 中为 Car1 分配了内存。您将其传递给函数。
    • 它构建、编译和运行正常,所以我确定。下次上课的时候我得问问我的教授。好的,我现在明白了,感谢您的帮助!
    • @MichaelBenton malloc 在 stdlib.h 中声明。
    • @MichaelBenton “为什么我不需要先为我的数据结构分配内存?” - 呃,你做到了?看到那些malloc 电话了吗?
    【解决方案2】:

    该问题是由 PrintedOutCarInfo() 中的内存分配引起的。 在 EnterCarInfo() 中,您正在为 Car 及其成员(字符串)分配必要的内存,并用用户的输入填充它们。 当您在 EnterCarInfo 中再次分配 Car 结构及其成员时,您正在破坏对原始 Car 结构及其成员的引用。 如果删除 EnterCarInfo() 的前 4 行,程序应该可以工作。 附带说明一下,这个应用程序可以用于学习/演示,但是分配一个固定的内存块来接收用户输入而不强制执行大小限制并不是一个好主意。未能检查限制将使您面临缓冲区溢出攻击。 希望这会有所帮助。

    【讨论】:

    • 这个问题是我必须动态分配我的数据结构,为此我需要前 4 行代码。除非我错了并且动态分配意味着我没有做的其他事情。
    【解决方案3】:

    正如 Harry 在下面所说,您正在覆盖 PrintedOutCarInfo() 中的指针。该函数应如下所示:

    void PrintedOutCarInfo(Car *host)
    {
        printf("The car's manufacturer is %s\n", host->Manufacturer);
        printf("The car's model is %s\n", host->ModelNameOfCar);
        printf("The color of the car is %s\n", host->ColorOfCar);
        printf("The year the car was made is %d\n", host->YearOfCar);
    }
    

    Malloc() 分配(保留)给定数量的内存供您的应用程序使用,然后返回指向该内存块开始地址的指针。您已经在 EnterCarInfo() 中分配了所需的内存,因此当您在 PrintedOutCarInfo() 中第二次调用 Malloc() 时,您正在分配内存中的另一个空间,然后将 AutoMobilesInfo 的指针指向内存中的那个新位置。 EnterCarInfo() 收集的数据仍在内存中,但它位于您的 AutoMobilesInfo 实例不再引用的旧位置。因此,当您 printf() 数据时,您正在打印新分配的内存块中的任何垃圾。

    【讨论】:

    • 是的,我现在明白了一点。我没有意识到我也将它分配在 main 中。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 2015-08-05
    • 2020-02-03
    相关资源
    最近更新 更多