动态分配的指向结构(链表)的指针数组,以及如何访问每个列表?

Posted

技术标签:

【中文标题】动态分配的指向结构(链表)的指针数组,以及如何访问每个列表?【英文标题】:Dynamically allocated array of pointers to structs(linked lists), and how to access each list? 【发布时间】:2020-09-09 09:29:42 【问题描述】:

我搜索了很多,我发现了类似的问题,但我仍然无法解决我的问题。 我想为指向表的指针数组分配内存(每个表都有自己的链表) 我希望我正确地解释了这个想法,这是代码:

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

typedef struct Meal 

    struct Meal* next;
    char* productname;
    int price;
    int quantity;
Meal, * PMeal;

typedef struct Table //each table is supposed to have its own linked list of meals

    PMeal next;
    PMeal prev;
    int tableNumber;
    int cheque; 
Table;

typedef struct allTables 

    int maxoftables;
    Table** tarray;       
    int numberoftables;
allTables;

这就是我尝试动态分配指向表的指针数组的方式:

(我认为这部分是正确的,它不会崩溃)

    allTables tables;
    tables.tarray = (Table**)malloc(sizeof(Table*) * tables.maxoftables)

注意:tables.maxoftables 是在调用 malloc 之前初始化的,是表的最大数量

这就是我尝试初始化每个表中的链表的方式:

(这是它告诉我“访问冲突写入位置”的地方)

for (i = 0; i < tables.maxoftables; i++)
            
                (tables.tarray[i])->cheque = 0;
                (tables.tarray[i])->next = NULL;
                (tables.tarray[i])->prev = NULL;
                (tables.tarray[i])->tableNumber = i + 1;
            

我相信我可以只分配一个结构表数组,但这是不允许的。

我希望您帮助我所需的一切都在这里并且得到了正确的解释

谢谢!

【问题讨论】:

【参考方案1】:

您的代码示例已接近完成。分配为 N 个指针保留了适当的空间,但它们指向什么? malloc() 的内存范围未初始化,可能是随机/剩余数据。 calloc() 将分配内存并将范围清除为零;结果是所有表指针都为 NULL。这也使您在遇到运行时异常时很容易发现错误的指针。

如果使用 calloc() 并且稍后在分配 .cheque (或其他结构成员)时,写入内存时的目标地址将以结构指针(NULL)加上结构成员的 X 字节偏移量开始:

// pseudo code
(NULL + small-byte-offset) <-- 0

虚拟内存的第一页可以称为“零页”。在您的用户程序中,大多数情况下,零页被有意保留为未映射,并且对于调试此类情况很有用。

虽然表指针 数组已被充分分配,但它们并未指向任何有效内存。您还需要分配 .maxoftables 结构 并使用分配的指针引用它们。

不幸的是,分配一个结构数组在某种程度上是不允许的,因为用一个请求分配一个数组是快速/便宜的。相反,您必须采用像这样的低效方法:分配一个表 结构 并检查并为指针数组的每个元素分配分配结果。

使用 calloc() 进行分配时的旁注:由于您的所有结构成员都将为零,这会带来一个附带好处,即您的示例中只需初始化 1 个结构成员 (i + 1)。

【讨论】:

以上是关于动态分配的指向结构(链表)的指针数组,以及如何访问每个列表?的主要内容,如果未能解决你的问题,请参考以下文章

数据结构单链表,双链表,数组的底层实现原理

如何得到指针指向的数组的长度

iOS - 链表

静态链表和动态链表的区别

C - 链表 - 如何分配和遍历列表

指向 C++ 中动态分配的二维数组中的一行的指针