从void **转换为int

时间:2013-08-27 04:28:55

标签: c pointers casting void-pointers

我有一个存储在void**指针中的动态2D数组,我只是想知道我应该如何转换/取消引用它们以便打印它们?

这是我想要做的一个例子:

/* 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-&gt;图形,因为它需要保存多种类型的数据,唯一一个我在实现时遇到问题的是int **数组。

我将矩阵=(int * )graph-&gt; graph更改为graph-&gt; graph =(void *)矩阵并且工作正常,我能够打印数组的元素,但是现在如果我实现一个单独的功能:

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 *图形)中运行该代码块,它会打印出2D数组。

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

1 个答案:

答案 0 :(得分:1)

假设:

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)来释放分配的内存。