0

メインの構造体の配列にメモリを割り当てようとしているプログラムを書いています。次に、ファイルからデータを読み取り、構造体を作成し、作成された構造体を配列に入力する関数に配列を渡します。

何らかの理由で、このコードは配列内の 7 つの要素に十分なメモリしか割り当てていません。

int assets_size = count_lines("rescue_assets.txt");
asset *assets;
assets = (asset*)malloc(sizeof(asset)*assets_size);

ファイル内の行数は 37 で、メインでテストされているように count_lines メソッドが機能します。

以下はメインの完全なコードです。

int main(int argc, char** argv) {
    int i;
    int assets_size = count_lines("rescue_assets.txt");
    asset *assets;
    assets = (asset*)malloc(sizeof(asset)*assets_size);
    ship ships[100];

    printf("%d\n", assets_size);

    printf("%lu\n", sizeof(assets));

    read_data(assets, ships);

    printf("%lu\n", sizeof(assets));

    for (i=0; i<sizeof(assets)-1; i++) {
        printf("%d\n", assets[i].deployment_time);
    }
    free(assets);
    return (EXIT_SUCCESS);
}

以下は関数 read_data に関連するコードです。

void read_data(asset *assets, ship ships[]) {
int max_assets;
int max_ships;
FILE *asset_file_ptr;
FILE *ship_file_ptr;
int count = 0;
int file_max = 100;
char asset_file[file_max];
char ship_file[file_max];

asset_file_ptr = fopen("rescue_assets.txt", "r");

if (asset_file_ptr == NULL) {
   printf("The asset file could not be opened."); 
   exit(0);       
}
else {
    char callsign[file_max];
    char type;
    char placename[file_max];
    double base_longitude;
    double base_latitude;
    double speed;
    int deployment_time;
    int service_time; 

    while (fscanf(asset_file_ptr, "%s %c %s %lf %lf %lf %d %d", callsign, &type,    placename, &base_longitude, &base_latitude, &speed, &deployment_time, &service_time)!= EOF) {
        asset* new_asset = malloc(sizeof(asset));
        new_asset->callsign = callsign;
        new_asset->type = type;
        new_asset->placename = placename;
        new_asset->base_longitude = base_longitude;
        new_asset->base_latitude = base_latitude;
        new_asset->speed = speed;
        new_asset->deployment_time = deployment_time;
        new_asset->service_time = service_time;

        assets[count] = *new_asset;
        count++;
    }
}
fclose(asset_file_ptr);

}

メインを実行して得た出力は次のとおりです。

37 8 8 600 180 180 818 180 600

プログラムは最初に assets_size を出力します。これは 37 です。次に、assets 配列のサイズを出力します。これは 37 のはずですが、8 です。これも同じです。次に、アレイに取り込まれたすべてのアセットのデプロイ時間を出力しますが、これはわずか 7 です。

どこが間違っているのか誰か教えてください。

4

1 に答える 1

3

問題は、展開時間を出力するためのメインの for ループにあります。sizeof(assets)配列の長さはわかりません。単純なポインターによってのみ指される配列の長さを取得する方法はありません。sizeof(assets)明らかに64ビットプラットフォームで作業しているため、ポインターのサイズを文字で示します。これは8です。0 から まで実行するだけasset_sizeです。

read_dataまた、アセットごとに新しい構造体を malloc するのはなぜですか。アセット配列に直接書き込むだけです。

主に次のことを行います。

for (int i = 0; i < size_assets; ++i)
    printf("%d\n", assets[i].deployment_time);

read_data で次のことを行います。

asset* asset_p = assets;
while (fscanf(...) != EOF) {
    asset_p->field = data;
    ...
    ++asset_p;
}

または代わりに:

int i = 0;
while (fscanf(...) != EOF) {
    assets[i].field = data;
    ...
    ++i;
}

またはさらに別の方法:

for (int i = 0; fscanf(...) != EOF; ++i) {
    assets[i].field = data;
    ...
}
于 2013-11-14T15:52:54.463 に答える