-1

動的な 2D 配列を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 ** のグラフを作成できません。実装に問題があるのは 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 配列が正常に出力されます。

別の関数から呼び出すと印刷されないように、グラフ->グラフに何が起こっているのか誰かが説明してもらえますか

4

1 に答える 1

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)もちろん、割り当てられたメモリを解放する関数も必要です。

于 2013-08-27T04:48:51.250 に答える