1

多くの組み合わせを試しましたが、実際には何も機能しませんでした。長くなってしまったので、この記事を書くことにしました。

構造体へのポインターの配列が必要なだけなので、後でアドレスを交換することで簡単に並べ替えることができます。ファイルからデータを取得して配列に書き込む関数があります。残念ながら、関数の外でこのデータを読み取ることはできません。

私の最後の試み(ファイル操作は問題ではないため、削除しました):

Header.h:

#pragma once

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

typedef struct {
    int32_t year;
    uint16_t month;
    uint16_t day;
} Date;

typedef struct {
    char name[16];
    Date date;
    uint32_t number;
} Player;

size_t readData(Player** players);

ソース.c:

#include "Header.h"

size_t readData(Player** players) {
    players = NULL;

    players = realloc(players, sizeof(Player*) * 1);
    players[0] = malloc(sizeof(Player));
    strcpy(players[0]->name, "asd");
    printf("$ %s\n", players[0]->name);//OK

    return 1;
}

int main() {
    Player **players = NULL;
    uint32_t elemCount, i;

    elemCount = readData(players);

    printf("> %s", players[0]->name);//BUM - ERROR!

    return 0;
}

私は Visual Studio Community 2015 を使用しています。C でコーディングするのはそれほど重要ではないことはわかっていますが、ソリューションを構成することができましたが、それは問題ではないようです。

私は助けてくれてとても感謝しています。それでも、自分のコードのリメイクとして見たいと思っています。このような StackOverFlow に関する質問に対する他の回答をいくつか試しましたが、役に立ちませんでした。

4

3 に答える 3

1

readData() に渡されるパラメーターは、呼び出し元のポインター 'players' のアドレスでなければなりません

readData() 内の各参照は、playersそれを考慮に入れる必要があります。

そうしないと、呼び出し元のポインター 'player' は更新されません。

次に、main() 関数、printf() の呼び出しがアドレス 0 から出力を試み、結果として未定義の動作が発生し、セグ フォールト イベントが発生します。

main() 関数で、以下を挿入した場合:

printf( "player value; %p\n", (void*)players);

playersprintf() への現在の呼び出しの前に、ポインターにまだ NULL が含まれていることがわかります。

于 2016-01-16T15:05:11.447 に答える
1

関数へのポインターを値で渡しています。元のまま変更されていませplayersん。これは、次のことと同じです。main

#include <stdio.h>

void func(int x)
{
    x = 4;
}

int main()
{
    int x = 0;
    func(x);

    printf("%d\n", x);      // zero
}

混乱させたのはポインターだと思いますので、今すぐ間違いを確認してください。

の外部で変更を可視化するにはreadData、3 つのレベルの間接化を使用する必要があります。

size_t readData(Player*** players) {
    *players = malloc(sizeof(Player*) * 1);
    *(players)[0] = malloc(sizeof(Player));
    strcpy((*players)[0]->name, "asd");
    printf("$ %s\n", (*players)[0]->name);//OK

    return 1;
}

int main() {
    Player **players = NULL;
    uint32_t elemCount, i;

    elemCount = readData(&players);

    printf("> %s", players[0]->name);  // prints 'asd'

    return 0;
}

渡されるポインタが alwaysであることがわかっreallocている場合に使用しても意味がないので、代わりに に変更しました。NULLmalloc

余談ですが、Visual Studio は C 開発に完全に適しており、C99 や C11 の一部を実装しています (歴史的に、MSVC は常に C89 のままでした)。ソース ファイルに拡張子を使用するだけで.c、コンパイラはコードが C であると見なすか、プロパティ ページで明示的に設定できます。

于 2016-01-15T17:56:56.157 に答える