如何在C中为我的数据结构分配内存

时间:2016-04-04 22:58:13

标签: c pointers data-structures malloc

我不明白为什么我的代码在用户输入数据后打印出垃圾变量。在我的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;
}

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

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

答案 2 :(得分:0)

正如哈利在下面所说,你正在覆盖 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()数据时,你将打印新分配的内存块中的垃圾。