【问题标题】:Dynamic Memory Allocation for Struct in C LanguageC语言中结构的动态内存分配
【发布时间】:2020-02-16 16:14:35
【问题描述】:

我正在复习一些 C 编程,并试图理解为什么在为结构动态分配内存后无法从结构 (struct) 打印数据项。

我尝试打印结构中的数据项以查看我得到的值,但我的代码无法编译,并且出现错误。

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

 typedef struct Collection {

     int age;
     char date[20];
     char name[20];
 } Collection;

 int main(void) {

     int i;
     int n = 10;

     Collection **dataCollection;
     dataCollection = malloc(sizeof(Collection*)*n);
     dataCollection->age = 20;

for(i = 0; i < n; i++) {

    dataCollection[i] = malloc(sizeof(Collection)*n);
    printf("Data collection item: %d\n", dataCollection->age);
}

for(i = 0; i < n; i++)
    free(dataCollection[i]);
   free(dataCollection);
   return 0;
 }

我收到以下错误:

practice1019.c:18:20: error: member reference base type 'Collection *' (aka 'struct Collection *')
      is not a structure or union
     dataCollection->age = 20;
     ~~~~~~~~~~~~~~^ ~~~

practice1019.c:23:56: error: member reference base type 'Collection *' (aka 'struct Collection *')
      is not a structure or union
    printf("Data collection item: %d\n", dataCollection->age);

【问题讨论】:

  • dataCollectionCollection**,但您将其视为 Collection*。首先适当地命名您的类型和变量; “收藏”不是收藏记录的最佳名称(与收藏本身相反)
  • dataCollection-&gt;age = 20; 尝试取消引用 dataCollection(此时它只不过是指向包含 10 个未初始化 指针 的内存块的指针。不会工作。
  • 并且您在最后一个 for 循环中有多个 free(dataCollection)。你应该把它拿出来。线条在那里,但位置不正确:)

标签: c pointers struct dynamic-memory-allocation dataitem


【解决方案1】:

从注释继续,您不能在仅分配一块足以容纳10 指向Collection 的内存块之后分配dataCollection-&gt;age = 20;。您为指针分配了内存,但没有为结构本身分配存储空间。

此外,您必须验证每个分配,例如

    dataCollection = malloc(sizeof(Collection*)*n);

    if (!dataCollection) {  /* validate EVERY allocation */
        perror ("malloc-dataCollection");
        return 1;
    }

现在,在为任何结构的成员赋值之前,您必须分配一块内存来保存该结构,然后将该块的起始地址分配给您刚刚分配的指针之一,例如

    for (i = 0; i < n; i++) {
        dataCollection[i] = malloc(sizeof(Collection));
        if (!dataCollection[i]) {   /* ditto */
            perror ("malloc-dataCollection[i]");
            return 1;
        }

注意:上面没有* nsizeof(Collection) 中的Collection 之后——否则您将在结构存储上过度分配10...)

现在,你有一个结构的存储空间,你可以使用成员(age 下面)

        dataCollection[i]->age = i + 20;
        printf("Data collection[%d] age: %d\n", i, dataCollection[i]->age);
    }

在每个结构的free 上做得很好,然后是指针。总而言之,您可以这样做:

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

typedef struct Collection {
    int age;
    char date;
    char name;
} Collection;

int main (void) {

    int i;
    int n = 10;

    Collection **dataCollection;
    dataCollection = malloc(sizeof(Collection*)*n);

    if (!dataCollection) {  /* validate EVERY allocation */
        perror ("malloc-dataCollection");
        return 1;
    }

    for (i = 0; i < n; i++) {
        dataCollection[i] = malloc(sizeof(Collection));
        if (!dataCollection[i]) {   /* ditto */
            perror ("malloc-dataCollection[i]");
            return 1;
        }
        dataCollection[i]->age = i + 20;
        printf("Data collection[%d] age: %d\n", i, dataCollection[i]->age);
    }

    for(i = 0; i < n; i++)
        free(dataCollection[i]);
    free(dataCollection);
}

使用/输出示例

$ ./bin/datacollection
Data collection[0] age: 20
Data collection[1] age: 21
Data collection[2] age: 22
Data collection[3] age: 23
Data collection[4] age: 24
Data collection[5] age: 25
Data collection[6] age: 26
Data collection[7] age: 27
Data collection[8] age: 28
Data collection[9] age: 29

检查一下,如果您有任何问题,请告诉我。

【讨论】:

  • 我想为 验证每个分配 +2。从“高级”语言进入 C 的人们倾向于假设每个 malloc() 都可以工作......直到它不起作用。
  • 是的,这不是"if" 的问题,而是"when" 的问题,它会失败:)
猜你喜欢
  • 2017-10-02
  • 2011-09-13
  • 1970-01-01
  • 2021-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多