繁体   English   中英

将 *void 项添加到 *void 数组中时,编译器如何知道要在内存中使用多少字节?

[英]When adding a *void item into an array of *void, how does compiler know how many bytes to use in memory?

我最近开始学习更多关于数据结构的知识,然后,在C 中实现队列概念时,我遇到了以下问题:

typedef struct {
  int max;        /* Max. enqueed items. */
  int total;      /* Total enqueued. */
  int pos_start;  /* Pos. of first item. */
  int pos_end;    /* Pos. of last item. */
  int item_size;  /* Byte size of each item. */
  void** items;   /* Array of items. */
} queue_t;

/* 
 * Omitted code for brevity purposes. 
 */

void
queue_add(queue_t* queue, void* item)
{
  if (queue_full(queue))
  {
    fprintf(stderr, "Tried to add an item into a full queue");
    exit(1);
  }

  queue->items[queue->pos_end] = item;
  queue->total++;
  queue->pos_end = find_next_end(queue);
}

显然它有效。 一些注意事项:

  1. 原始教程教了如何创建整数队列。 我试图通过创建一个“任何”元素的队列来挑战自己 - 这就是我尝试使用void*元素数组的原因。
  2. 由于我使用的是void*元素数组,因此我知道,无论何时我想使用此队列中的任何项目(例如,在主要功能中使用queue_pop ),我都需要进行适当的转换。 通过使用强制转换,编译器可以准确地知道该变量应该在内存中占用多少字节。

但是,我的大问题是

根据我的功能,当我将新项目推入队列时,我将其保存到queue->items[queue->pos_end] 如果编译器不知道item有多少字节(因为它被标记为void* ),它如何计算queue->items[queue->pos_end]的内存地址?

编译器不知道项目有多少字节(因为它被标记为void*

编译器确切地知道item由多少个字节组成,因为它的类型是一个指针(指向voidint ,或指向另一个指针,或指向其他任何东西 - 无关紧要),并且所有指针的大小都相同(通常4 或 8 个字节)。

指针总是完整的类型,包括(可能是 cv 限定的)指针类型void *void **

来自 C 标准(6.2.5 类型,p.#20)

— 指针类型可以从函数类型或对象类型派生,称为引用类型。 指针类型描述了一个对象,其值提供对被引用类型的实体的引用。 从引用类型 T 派生的指针类型有时称为“指向 T 的指针”。 从引用类型构造指针类型称为“指针类型派生”。 指针类型是一个完整的对象类型。

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    printf( "sizeof( void * ) = %zu\n", sizeof( void * ) );

    return 0;
}

它的输出可能是

sizeof( void * ) = 8

因此,如果您有一个元素类型为void *的数组,那么编译器在相对于访问数组元素的指针算术中使用值 8。

暂无
暂无

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

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