Take a closer look to your function.
void menu_init(struct menu_item * menu_items[NUM_MENU_ITEMS]) { /* allocate memory for each element in the array */ menu_items[NUM_MENU_ITEMS] = (struct menu_item *) malloc(sizeof(struct menu_item)); }
You need to carry the size of the array in a second parameter in your function. However, NUM_MENU_ITEMS, seems to be a global #define, thus you don't need to carry a second parameter.
Then you are accessing an out of bound cell, menu_items[NUM_MENU_ITEMS]. I assume you know that the indexing starts from 0 and ends at NUM_MENU_ITEMS-1.
In your function, you need, inside a loop, to allocate memory. Moreover, you don't need to cast what malloc returns.
So, for example, you could do something like this:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define ITEM_NAME_LEN 15 #define NUM_MENU_ITEMS 3 // Define the struct before main struct menu_item { char name[ITEM_NAME_LEN + 1]; }; // Give a synonym. Now struct menu_item is the same with menu_item_t. // Notice the _t extension, which implies that this is a typedef. typedef struct menu_item menu_item_t; /** * Given a pointer 'p' to an array of pointers * (of type menu_item_t), allocate memory for * every cell of the array. */ void init_menu(menu_item_t* p[]) { int i; for(i = 0; i < NUM_MENU_ITEMS; ++i) { // for every cell of our array, allocate memory p[i] = malloc(sizeof(menu_item_t)); // check that allocation for the i-th cell is OK if(!p[i]) { printf("Error in allocating %d item!\n\n", i); return; } } } /** * Given a pointer 'p' to an array of pointers * (of type menu_item_t), de-allocate memory for * every cell of the array. */ void delete_menu(menu_item_t* p[]) { int i; for(i = 0; i < NUM_MENU_ITEMS; ++i) { // free the memory we had allocated for the i-th cell free(p[i]); // set the pointer to NULL p[i] = NULL; } } void fill(menu_item_t* p[]) { int i; for(i = 0; i < NUM_MENU_ITEMS; ++i) { strcpy(p[i]->name, "myitem"); } } void print(menu_item_t* p[]) { int i; for(i = 0; i < NUM_MENU_ITEMS; ++i) { printf("%s\n", p[i]->name); } } int main(void) { // Declare an array of pointers of menu_items_t. // The size of the array is NUM_MENU_ITEMS menu_item_t *menu_items[NUM_MENU_ITEMS]; init_menu(menu_items); fill(menu_items); print(menu_items); delete_menu(menu_items); return 0; }
When I deal with structs, I always have this example on mind.
struct menu_item * menu_items[3];for some guidence.init_menu(&menu_items[NUM_MENU_ITEMS]);passes a pointer to the non-existent element just off the end of the array. Just lacking some basic knowledge of syntax, here.