Kirill Murashkin
Kirill Murashkin

Reputation: 301

Access to global array of structures in C

The problem in short

I update global array of structures in one file (add_product.c), but can't print these updates out in another file (show_list.c).

Details

If you need a full image, look at github repo

Here is the essence.

The program I write let user does the following:

  1. Create a list of products
  2. Add a product on existing list
  3. Show all the products on the list

... and consists of 4 files:

global-variables.h

#define LIST_OF_PRODUCTS_INITIAL_LENGTH 50

struct Product {
    char name[50];
    float price;
    unsigned int amount;
};

extern struct Product *list_of_products[LIST_OF_PRODUCTS_INITIAL_LENGTH];
extern unsigned int current_list_of_products_length;

main.c

struct Product *list_of_products[LIST_OF_PRODUCTS_INITIAL_LENGTH];
unsigned int current_list_of_products_length = 0;

add_product();

show_list();

add_product.c

int add_product() {
    ...

    struct Product new_product;

    list_of_products[current_list_of_products_length] = &new_product;

    current_list_of_products_length++;

    // For example, cheese
    scanf("%s", &list_of_products[current_list_of_products_length]->name);
    fflush(stdin);

    scanf("%f", &list_of_products[current_list_of_products_length]->price);
    fflush(stdin);

    printf("Enter the amount of %s: ", list_of_products[current_list_of_products_length]->name);
    scanf("%d", &list_of_products[current_list_of_products_length]->amount);
    fflush(stdin);

    list_of_products_exists = true;

    // **NOTICE**! All the values here are printed correctly (cheese  15    150)
    printf("Name: %s \n", list_of_products[current_list_of_products_length]->name);
    printf("Price: %.2f\n", list_of_products[current_list_of_products_length]->price);
    printf("Amount: %d\n", list_of_products[current_list_of_products_length]->amount);

    ...
};

show_list.c THE PROBLEM IS HERE!

int show_list() {
    ...
    
    current_product = *list_of_products[0];

    // EXPECTED cheese  15    150
    // ACTUAL   @6є     0     0.00
    printf("%10s %10d %10.2f", current_product.name, current_product.amount, current_product.price);

    ...
}

Upvotes: 0

Views: 552

Answers (2)

MikeCAT
MikeCAT

Reputation: 75062

    struct Product new_product;

    list_of_products[current_list_of_products_length] = &new_product;

is bad because new_product is local to this block and not static, so this will be invalidated when rethrning from the function and the pointer become useless.

You should allocate memory dynamically like this instead:

    list_of_products[current_list_of_products_length] = malloc(sizeof(struct Product));

Also this line invokes undefined behavior by type mismatch and the & should be removed.

    scanf("%s", &list_of_products[current_list_of_products_length]->name);

Also fflush(stdin); invokes undefined behavior, so you shouldn't use that.

Upvotes: 1

goodvibration
goodvibration

Reputation: 6206

Doing this inside a function:

struct Product new_product;
list_of_products[current_list_of_products_length] = &new_product;
...

Yields undefined behavior once you're outside of the function.

This is because the local variable new_product is no longer viable at this point, hence it is undetermined what resides at the address &new_product (where this variable was allocated during the execution of the function).

Upvotes: 1

Related Questions