【问题标题】:Accessing struct pointer within another struct in C在C中访问另一个结构中的结构指针
【发布时间】:2016-09-20 04:22:12
【问题描述】:

我有一个类型node,它的指针正在另一个结构中使用,如下所示。

typedef struct element {
    void* data;
    struct element *next;
} node;

typedef struct queue {
    node *tail;
    node *head;
    int num_items;
} queue_t;

我使用以下代码创建了一个空队列,但我不确定是否应该将 head 和 tail 设置为 NULL,因为 temp 还没有指向任何地方。

queue_t *temp;
temp = malloc(sizeof(queue_t));
if (temp == NULL){
return NULL;
}
temp->head = NULL;
temp->tail = NULL;
temp->num_items = 0;

根据我的理解,malloc 只会将临时指向某个地址空间,其大小等于struct queue_t 的大小。地址空间尚不包含有效的队列元素。那么temp->head = NULL;temp->tail = NULL; 是怎样的有效语句呢? 有人可以解释一下为什么会这样吗?

【问题讨论】:

  • 如果你在标题中说“C”,也不要用 C++ 标记。选择一种语言;坚持下去。
  • 代码中没有struct Node;你有一个struct element,也称为node,你有一个struct queue,也称为queue_t
  • 您分配了一个“结构队列”(又名 queue_t),然后在分配的结构中设置成员变量的值。为什么它不起作用? (也许您读到了有关未定义分配空间中的字节的信息?这是真的,但只有当您读取未定义的值而不是覆盖它们时才会出现问题)

标签: c pointers struct


【解决方案1】:

地址空间还没有包含有效的队列元素。

正确,分配的内存只包含一个queue_t

那么 temp->head = NULL 怎么样?和 temp->tail = NULL;有效的陈述?

headtail 不是 struct element 的一部分。 headtailqueue_t 的一部分。您已经分配了一个queue_t,因此可以将值分配给headtail。在这种情况下,您分配 NULL 值以表明它们尚未指向任何有效的东西。

当您分配node(又名结构元素)时,您会更新headtail,例如:

// Add first node
temp->head == malloc(sizeof(node));
temp->tail == temp->head;
if (temp->head == NULL){
    return NULL;
}
temp->num_items = 1;

// Initialize the new node
temp->head->next = NULL;   
temp->head->data = NULL;   

// Note: Adding more node requires more complex code

【讨论】:

    【解决方案2】:

    “有效队列元素”的定义是什么?如果它是“足够的空间来保存队列元素并且保存头和尾指针的位置具有有效值”,那么将它们设置为NULL 使其有效。如果不是,那是什么?

    【讨论】:

      【解决方案3】:

      据我了解,malloc 只会将临时点指向某些 地址空间的大小等于struct queue_t的大小。

      正确。

      地址空间还没有包含有效的队列元素。

      不知道你所说的“有效”是什么意思,但这种说法也是正确的。

      那么 temp->head = NULL 怎么样?和 temp->tail = NULL;有效的陈述?

      正是这些语句使您分配的空间成为有效的队列元素!

      有人能解释一下为什么会这样吗?

      您的问题基本上与int i; 之类的声明没有什么不同。您的实现留出一个空间来保存整数。然而,它仍然是无效的,因为你没有给它任何(有意义的)价值。一旦你设置了i = 0;i = 42;,你调用i 的空间现在是一个有效的整数。

      希望对您有所帮助。

      【讨论】:

        【解决方案4】:

        据我了解,malloc 只会将 temp 指向某个地址空间,其大小等于 struct queue_t 的大小。

        malloc 函数调用返回一个地址,该地址指向malloc 函数调用参数中指定大小的分配内存的开头(以字节为单位)。分配的内存空间大小将在malloc 的参数中指定。但是,malloc 返回的地址将是该内存空间的开头。因此,您可以使用指向该内存空间的指针安全地访问该内存空间的大小。

        地址空间还没有包含有效的队列元素。

        C 标准库为指针变量temp 分配了一个有效的内存空间来指向。但是,存储在该内存空间中的值可能是垃圾。因此,指向nodenum_items 数据成员的指针在queue_t 中分配了一些有效内存空间可能具有垃圾值。例如,为queue_t分配内存后,可以尝试使用printf函数打印num_items的值。

        queue_t *temp = malloc(sizeof(queue_t));
        if (temp == NULL){
            return NULL;
        }
        printf("The value of num_items: %d\n", temp->num_items);
        

        上面的例子可以打印任何垃圾值。因为,C language 没有构造函数来初始化新创建的变量,所以你应该用一些稳定的值来初始化你创建的每个变量。

        您还可以使用calloc 函数调用,该函数在分配内存空间后还将分配的内存设置为zero

        那么 temp->head = NULL 怎么样?和 temp->tail = NULL;有效的陈述?

        内存由malloc 分配,其中可能包含任何垃圾值。 queue_t 的数据成员共享该内存空间。由于内存空间可能包含垃圾数据,因此数据成员将包含任何随机垃圾数据。这就是为什么将malloc 分配的结构的data members 初始化为一些稳定值的好方法。这就是你在你的程序中所做的。

        其实temp的数据成员headtail应该指向node类型变量的地址。 malloc 调用分配了pointer variables。这些指针变量可以指向node 类型的任何变量(或存储node 类型变量的地址)。但是您还没有分配任何node 变量并且您不想创建dangling pointer。因此,您应该使用NULL 初始化这些pointer variables

        您的程序应如下所示:

        queue_t *temp;
        temp = malloc(sizeof(queue_t));
        if (temp == NULL){
            return NULL;
        }
        temp->head = NULL;
        temp->tail = NULL;
        temp->num_items = 0;
        
        //Allocate some node
        node *n = malloc(sizeof(node));
        int data = 1;
        n->data=&data;
        n->next=NULL;
        temp->head=n;
        temp->tail=n;
        temp->num_items=1;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-07-13
          • 1970-01-01
          • 1970-01-01
          • 2015-07-10
          • 2014-06-09
          • 1970-01-01
          • 2018-04-25
          • 1970-01-01
          相关资源
          最近更新 更多