繁体   English   中英

如何使用 malloc 为结构数组动态分配 memory?

[英]How can you allocate memory dynamically for an array of structs using malloc?

我想在 C 中实现一个简单的数据库,我需要使用一个结构数组并在需要调整大小时重新分配它。
经过不断的努力,我意识到我不能将 malloc 用于结构数组,因为 malloc 返回一个指针,所以我不能在等号的左侧有一个结构。 所以我的问题是:

你怎么能 malloc 一个结构数组?

给定一个指向结构数组的第一个结构的指针p ,您可以使用p[i]访问索引为i的结构。

您可以像这样分配和初始化结构数组:

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


typedef struct { int MyInteger; } MyStructure;


MyStructure *GiveMeAnArrayOfStructures(size_t NumberOfStructures)
{
    //  Allocate memory.
    MyStructure *p = malloc(NumberOfStructures * sizeof *p);
    if (!p)
    {
        fprintf(stderr, "Error, unable to allocate memory.\n");
        exit(EXIT_FAILURE);
    }

    //  Initialize structures.
    for (size_t i = 0; i < NumberOfStructures; ++i)
        p[i].MyInteger = i;

    //  Return array, via pointer to first element.
    return p;
}

此示例在赋值左侧使用结构成员,但我们也可以在左侧使用结构:

    for (size_t i = 0; i < NumberOfStructures; ++i)
    {
        MyStructure Example = { i };
        p[i] = Example;
    }

假设一个名为struct s的结构类型,你想为N个实例分配空间:

struct s *arr = malloc( sizeof *arr * N );

图形化:

      struct s *    struct s
      +---+         +---+
 arr: |   | ------> |   | arr[0]
      +---+         +---+
                    |   | arr[1]
                    +---+
                     ...
                    +---+
                    |   | arr[N-1]
                    +---+

换句话说, malloc 保留了足够的空间来存储 N 个结构,并返回一个指向该空间开头的指针,该指针存储在arr中。 您可以在指针和数组表达式上使用下标运算符[] ,因此您可以将每个结构称为arr[i]并将访问成员称为arr[i].member

大多数问题避免在“malloc”关键字之前使用类型转换。 它有什么好处? 我被告知总是在 malloc 之前使用类型转换。

在 C(称为 K&R C)的最早版本中,不存在void类型,并且无法声明像void *这样的“通用”指针。 在那些日子里, malloc (以及callocrealloc )返回一个char * ,所以如果你想将结果分配给不是char *的东西,你必须转换结果:

/** K&R C */
int *ptr = (int *) malloc( sizeof *ptr * N );

这在 1989 年的标准中发生了变化,它引入了void类型并创建了void *可以直接分配给其他指针类型的规则,从而使强制转换变得多余。 因此,从 C89 开始,您可以编写:

/** C89 and later */
int *ptr = malloc( sizeof *ptr * N );

演员表不再是必要的,我们大多数人建议不要使用它,因为它只会增加混乱和犯错的可能性(如果你忘记了#include <stdlib.h> ,在 C89 标准下可能会抑制有用的诊断)。 必须malloc结果的唯一时间是:

  • 您正在使用古老的 K&R 编译器;
  • 您正在将代码编译为 C++;

与 C 不同,C++不允许void *和其他指针类型之间直接赋值,并且需要您使用强制转换。 但是,如果您正在编写 C++,那么无论如何您都不应该使用malloc

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM