首页 文章

转换void指针并使用格式说明符进行打印

提问于
浏览
1

好的,这是一个学校项目,但我的问题有 nothing to do with anything regarding a specific implementation ,我也没有要求对项目本身提供任何帮助 . 我只是给出了这个警告,因为我想为我正在做的事情提供上下文,但这是关于在项目的上下文中构建的void指针的一般性问题...这个函数我甚至对于项目,它's just something I wrote as a testing mechanism to see if my generation of a data structure is working... and it lead me to a problem involving printf(), format specifiers, and casting.... I basically have to implement a linked-list (called a '队列'但根本不是一个队列),我写了一个函数来测试它 .

基本上有一个名为"Chunk"的结构,带有一些变量( first 是较大数组中的索引,是给定"Chunk"的第一个元素,而 arr 基本上是greater_array [c-> first],但它实际上是一个无效指针,因此: *void arr 其中c是指向Chunk的指针,指示较大数组中的位置 . 所以基本上如果你有一个类似a = {5,7,3,4,6,9,1,2}的数组,并且你得到的块大小为2,你有4个块,每个块都有一个"arr"无效指针变量分别指向5,然后是3,然后是6,然后是1 .

无论如何,我写了一个“print_queue”函数(实际上是一个Chunks的链接列表)和yay!它根据需要打印所有信息,这是我将分享的核心部分:

while (index < num_chunks) {
    first = c->first;
    printf("Chunk %d: first is %d and a[%d] is ", index, first, first);
    if (elem_size == LONG_SIZE) /* LONG_SIZE defined above as 8 */
      printf("%ld\n", c->arr);
    else if (elem_size == INT_SIZE) /* INT_SIZE defined above as 4 */
      printf("%d\n", c->arr);
    else if (elem_size == CHAR_SIZE) /* CHAR_SIZE defined above as 1 */
      printf("%c\n", c->arr);

    index++;

    if (c->next != NULL)
      c = c->next;
 }

我基本上想要编写一个函数,能够在我实现项目的实际功能(多线程合并排序)时为测试目的打印三种类型(long,int和chars)中的任何一种的链表 . 所以上面的代码实际上有效!这是此数组输入的输出:

char original[] = {'z', 'y', 'x', 'w', 'v', 'u', 't', 's'};

输出:

Chunk 0: first is 0 and a[0] is z
 Chunk 1: first is 2 and a[2] is x
 Chunk 2: first is 4 and a[4] is v 
 Chunk 3: first is 6 and a[6] is t

它有效!好极了!但是,我收到这些编译器警告:

mergesort.c: In function 'print_chunk_queue':
mergesort.c:85:7: warning: format '%ld' expects argument of type 'long int', but     argument 2 has type 'void *' [-Wformat]
mergesort.c:87:7: warning: format '%d' expects argument of type 'int', but argument 2 has type 'void *' [-Wformat]
mergesort.c:89:7: warning: format '%c' expects argument of type 'int', but argument 2 has type 'void *' [-Wformat]

所以我所做的是将所有c-> arr转换为(type *)c-> arr,但这给了我更多关于“哦,我们想要一个int但你有一个int指针”的警告,所以我做的是然后:

* ((type *) c->arr)

基本上解除引用我的casted void指针(它永远不会为null!它总是指向有效数字,至少我提供它的输入!),然后这给了我一个分段错误!所以我非常沮丧,因为我从工作输出到大量的“警告”到无用的分段错误 .

编辑:

根据要求定义数据结构:

typedef struct chunk {
  void *arr;
  struct chunk *next;
  int first;
} Chunk;

这就是我如何设置单个块的状态并创建块的链接列表:

while (index < number_of_chunks) {
    if (index == 0) {
      if ((current = malloc(sizeof(Chunk))) == NULL)
        err(EX_OSERR, "memory allocation has failed\n");
      head = current;
    }
    current->first = (chunk_size * index);
    current->arr = ((char *) array)[current->first];
    current->size = chunk_size;
    if (index != (number_of_chunks - 1)) {
      if ((current->next = malloc(sizeof(Chunk))) == NULL)
        err(EX_OSERR, "memory allocation has failed\n");
      current = current->next;
   }
  else {
    tail = current;
  }
  index += 1;
}

1 回答

  • 1
    current->arr = ((char *) array)[current->first];
    

    这里应该有 & . 您希望将字节的地址分配给 arr 而不是其值 .

    current->arr = &((char *) array)[current->first];
    

    如果你这样做,那么 arr 将包含一个类似于它的地址,这将允许强制转换和解除引用 .

    printf("%ld\n", *(long *) c->arr);
    printf("%d\n",  *(int  *) c->arr);
    printf("%c\n",  *(char *) c->arr);
    

相关问题