简体   繁体   中英

How to allocate memory for an array of structs, then pass that array to a function, which populates the array in C

I'm writing a program where I am trying to allocate memory for an array of structs in the main then pass the array to a function which reads data in from a file, creates the structs and populates the array with the structs created.

For some reason this piece of code is only allocating enough memory for 7 elements in the array;

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

The amount of lines in the file are 37 and the count_lines method works, as it is tested in the main.

Below is the complete code for the main;

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);
}

Below is the relevant code for the function 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);

}

Here is the output I get from running the main;

37 8 8 600 180 180 818 180 600

the program first prints out the assets_size, which is 37. then it prints out the size of the assets array, which should be 37, but is 8. same again. It then prints out the deployment time of all the assets that have been populated in to the array, which is only 7.

Please can someone tell me where I'm going wrong?

The problem is in your for loop in main to print the deployment times, sizeof(assets) does not give you the length of the array, there is no way to get the length of an array only pointed to by a simple pointer. sizeof(assets) gives you the size of a pointer in chars, which is 8 as you're apparently working on a 64 bit platform. Simply run from 0 up to asset_size .

And why are you mallocing a new struct in read_data for each asset, just write directly into the asset array.

In main do:

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

In read_data do:

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

or alternatively:

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

or yet alternatively:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM