从 void** 转换为 int

标签 c pointers casting void-pointers

我有一个动态二维数组存储在 void** 指针中,我只是想知道如何转换/取消引用这些值以便可以打印它们?

这是我正在尝试做的示例:

/* Assume that I have a data structure called graph with some 
 * element "void** graph" in it and some element "int order" */

void foo(graph_t *graph)
{
    int **matrix;

    /*safe malloc works fine, it uses calloc to initialise it all to zeroes*/
    matrix = safe_malloc(graph->order * sizeof(int*)); 

    for (i = 0; i < graph->order; i++)
        matrix[i] = safe_malloc(graph->order * sizeof(int));

    /* storing matrix in the data structure */
    matrix = (int**)graph->graph;

    printf("%d\n", (int)graph->graph[2][2]);
}

当我尝试编译它时,编译器给出警告:“取消引用‘void *’指针”,以及错误:“无效使用 void 表达式”。

我应该如何转换 void** 指针,以便可以打印 graph->graph 中的元素?

编辑:

感谢大家的帮助;我无法制作 int** 类型的 graph->graph,因为它需要保存多种类型的数据,我唯一在实现时遇到麻烦的是 int** 数组。

我将matrix = (int*)graph->graph更改为graph->graph = (void*)matrix,效果很好,我可以打印数组的元素,但是现在如果我实现一个单独的函数:

void print_foo(graph_t *graph)
{
    int i,j;

    for (i = 0; i < graph->order; i++)
    {
        for(j = 0; j < graph->order; j++)
        {
            printf("%d ", ((int**)graph->graph)[i][j]);
        }
        putchar('\n');
    }
}

它只是给了我一个段错误,但是如果我在原始 foo(graph_t *graph) 中运行该代码块,它会很好地打印 2D 数组。

有人可以解释一下 graph->graph 发生了什么,这样如果我从不同的函数调用它,它就不会打印

最佳答案

给定:

typedef struct graph_t
{
    int order;
    void **graph;
} graph_t;

并假设您将 graph->graph 分配为 int * 数组和一系列 int 数组,那么您可以,如果必须的话,请写:

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

typedef struct graph_t
{
    int order;
    void **graph;
} graph_t;

extern void *safe_malloc(size_t n);
extern void foo(graph_t *graph);

void foo(graph_t *graph)
{
    int **matrix;

    /*safe malloc works fine, it uses calloc to initialise it all to zeroes*/
    matrix = safe_malloc(graph->order * sizeof(int*)); 

    for (int i = 0; i < graph->order; i++)
        matrix[i] = safe_malloc(graph->order * sizeof(int));

    /* storing matrix in the data structure */
    graph->graph = (void **)matrix; // Reverse order of assignment
    // C compiler complains without the cast - the cast is nasty!

    printf("%d\n", ((int **)graph->graph)[2][2]);
}

代码应检查 graph->order >= 3 以避免溢出问题。

但是,该结构非常糟糕,并且 printf() 语句中必要的转换足以让您意识到为什么它很糟糕。在结构中使用 int **graph; 会更好:

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

typedef struct graph_t
{
    int order;
    int **graph;
} graph_t;

extern void *safe_malloc(size_t n);
extern void foo(graph_t *graph);

void foo(graph_t *graph)
{
    int **matrix;

    matrix = safe_malloc(graph->order * sizeof(int*)); 

    for (int i = 0; i < graph->order; i++)
        matrix[i] = safe_malloc(graph->order * sizeof(int));

    graph->graph = matrix;

    printf("%d\n", graph->graph[2][2]);
}

即使在严格的警告级别下,这两个编译器也不会发出警告。两者都没有通过创建 main() 函数来进行正式测试。当然,您还需要一个函数 bar(graph_t *graph) 来释放分配的内存。

关于从 void** 转换为 int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18456944/

相关文章:

c++ - 语句初始化属于哪一类?

c++ - C++中的指针按值/引用传递

c++ - 对象 move 后,指向const vector 成员变量元素的指针是否保持稳定?

c - 测试 “if (i && (i- 1))”是什么意思?

c - 确定 C 中 Z-lib 的压缩/未压缩缓冲区大小

c - 子进程退出后如何执行父进程?

c++ - C++中的**是什么

c - 连续应用两个显式指针转换?

java - 从插件项目中类转换解析 Java 源代码时出现问题

java - 为什么将 Type[] 转换为 Class[] 会抛出 ClassCastException?